如何在c#中调用x64汇编过程



我正在做一个项目,目前有以下结构:

  1. c# WPF项目包含用户界面以及对外部方法的调用。
  2. 包含一个算法的c++ DLL项目。
  3. 包含算法的ASM DLL项目。

为简单起见,我们假设该算法不接受任何参数,并返回两个预定义数字的和。

下面是c++(第二个)项目中的函数签名和实现:

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;
}

下面是我如何在c#中调用这个函数:

[DllImport("Algorithm.Cpp.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int RunCpp();

这工作得很好-在c#中调用函数返回值3,一切正常工作,没有抛出异常。

然而,我现在正在努力在c#代码中调用ASM过程。我已经看到(并在某种程度上测试了自己)在c#代码中直接调用MASM DLL是不可能的。然而,我听说可以在c++中调用ASM,然后在c#中调用该函数。

1。我的第一个问题是-调用ASM代码实际上可能直接在c# ?当我尝试时,我得到一个异常,基本上说二进制代码是不兼容的。2
我尝试使用c++间接调用ASM DLL,虽然我没有得到异常,但返回值是"随机",就像在内存中留下的余数一样,例如:-7514271。是我做错了什么,还是有其他方法可以做到这一点?

下面是c++中调用ASM的代码:
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;
}
这里,在c#中调用c++的代码:
[DllImport("Algorithm.Cpp.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int RunAsm();

Main.asm: MyProc1的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

调用ASM代码实际上可能直接在c#中?

两个项目的例子,c#和基于汇编的DLL。看起来你已经知道如何得到一个基于c++的DLL工作。项目名称与目录名称相同,xcs表示c#, xcall表示dll。我从空目录开始,创建空项目,然后将源文件移到目录中,然后将现有项目添加到每个项目中。

xcadll属性:

Configuration Type: Dynamic Library (.dll)
Linker | Input: xcadll.def

xcadll xcadll.def:

LIBRARY xcadll
EXPORTS DllMain
EXPORTS Example

xcadll xa。asm属性(对于发布版本,/Zi不需要):

General | Excluded From Build: No
General | Item Type: Custom Build Tool
Custom Build Tool | General | Command Line: ml64 /c /Zi /Fo$(OutDir)xa.obj xa.asm
Custom Build Tool | General | Outputs: $(OutDir)xa.obj

xcadll xa.asm:

includelib      msvcrtd
includelib      oldnames        ;optional
.data
.data?
.code
public  DllMain
public  Example
DllMain proc                            ;return true
mov     rax, 1
ret     0
DllMain endp
Example proc                            ;[rcx] = 0123456789abcdefh
mov     rax, 0123456789abcdefh
mov     [rcx],rax
ret     0
Example endp
end

xc Program.cs:

using System;
using System.Runtime.InteropServices;
namespace xcadll
{
class Program
{
[DllImport("c:\xcadll\x64\release\xcadll.dll")] 
static extern void Example(ulong[] data);
static void Main(string[] args)
{
ulong[] data = new ulong[4] {0,0,0,0};
Console.WriteLine("{0:X16}", data[0]);
Example(data);
Console.WriteLine("{0:X16}", data[0]);
return;
}
}
}

对于调试,使用

[DllImport("c:\xcadll\x64\debug\xcadll.dll")] 

xcs properties | debug |启用本机模式调试(勾选复选框)

相关内容

  • 没有找到相关文章

最新更新