I am working on a project and currently have the following structure:
- C# WPF project containing the User Interface as well as calls to external methods.
- C++ DLL project containing an algorithm.
- ASM DLL project containing an algorithm.
For simplicity, let's assume the algorithm simply takes no parameters and returns the sum of two, predefined numbers.
Here's the function signature and implementation in the C++ (second) project:
int Add(int x, int y)
{
return x + y;
}
extern "C" __declspec(dllexport) int RunCpp()
{
int x = 1, y = 2;
int z = Add(x, y);
return z;
}
And here's how I call the function in C#:
[DllImport("Algorithm.Cpp.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int RunCpp();
This works just fine - calling the function in C# returns the value 3, everything is working proplerly, no exceptions thrown.
However, I am now struggling to call the ASM procedure in C# code. I have seen (and tested myself to an extent) that it's impossible to call a MASM DLL directly in C# code. However, I've heard that it's possible to call ASM in C++ and call that function in C#.
1. My first question is - is calling ASM code actually possible directly in C#? When I try that, I get an exception that basically says the binary code is incompatible.
2. I have tried to use C++ to indirectly call the ASM DLL, and while I get no exception, the returned value is "random", as in, it feels like a remainder left in memory, for example: -7514271. Is this something I'm doing wrong, or is there another way to achieve this?
Here's the code for calling ASM in C++:
typedef int(__stdcall* f_MyProc1)(DWORD, DWORD);
extern "C" __declspec(dllexport) int RunAsm()
{
HINSTANCE hGetProcIDDLL = LoadLibrary(L"Algorithm.Asm.dll");
if (hGetProcIDDLL == NULL)
{
return 0;
}
f_MyProc1 MyProc1 = (f_MyProc1)GetProcAddress(hGetProcIDDLL, "MyProc1");
if (!MyProc1)
{
return 0;
}
int x = 1, y = 2;
int z = MyProc1(x, y);
FreeLibrary(hGetProcIDDLL);
return z;
}
Here, the code for calling C++ in C#:
[DllImport("Algorithm.Cpp.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int RunAsm();
And here's the ASM code of MyProc1
, if needed:
Main.asm:
MyProc1 proc x: DWORD, y: DWORD
mov EAX, x
mov ECX, y
add EAX, ECX
ret
MyProc1 endp
Main.def:
LIBRARY Main
EXPORTS MyProc1