是否有某种方法可以在 C# 应用程序中使用 C 源代码与内联汇编(这是不是C++ 代码)?我对如何完成并不挑剔,如果需要将 C/asm 与 C# 应用程序一起编译成 DLL,那就这样吧。我知道 C# 中没有使用汇编的规定,因此这个问题。
我试图合并的示例代码:
SomeFunc(unsigned char *outputData, unsigned char *inputData, unsigned long inputDataLength)
{
_asm
{
//Assembly code that processes inputData and stores result in outputData
}
}
在声明该函数之前,C 代码中有一些指针/变量声明,但除此之外都是内联汇编,如果有任何影响,这些声明将在汇编代码中使用。
目标是从 C# 传递“inputData”,然后以某种方式访问 C# 程序中的“outputData”。通常我们只是用原生 C# 重写汇编代码,但我们制作原型的时间安排很紧,如果我们可以暂时使用现有的 C/汇编代码,那么没有任何理由立即重新发明轮子。一些时尚。
其实很简单,甚至不需要反思。
[SuppressUnmanagedCodeSecurity]
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int AssemblyAddFunction(int x, int y);
[DllImport("kernel32.dll")]
private static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
byte[] assembledCode =
{
0x55, // 0 push ebp
0x8B, 0x45, 0x08, // 1 mov eax, [ebp+8]
0x8B, 0x55, 0x0C, // 4 mov edx, [ebp+12]
0x01, 0xD0, // 7 add eax, edx
0x5D, // 9 pop ebp
0xC3 // A ret
};
int returnValue;
unsafe
{
fixed (byte* ptr = assembledCode)
{
var memoryAddress = (IntPtr) ptr;
// Mark memory as EXECUTE_READWRITE to prevent DEP exceptions
if (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress,
(UIntPtr) assembledCode.Length, 0x40 /* EXECUTE_READWRITE */, out uint _))
{
throw new Win32Exception();
}
var myAssemblyFunction = Marshal.GetDelegateForFunctionPointer<AssemblyAddFunction>(memoryAddress);
returnValue = myAssemblyFunction(10, -15);
}
}
Console.WriteLine($"Return value: {returnValue}"); // Prints -5
我已经就此写了一篇博客文章。