是否有一些方法可以在 C# 应用程序中混合使用 C 源代码和内联 asm(这不是 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”。通常我们只是用 native C# 重写汇编程序代码,但我们的时间很紧,无法将原型(prototype)放在一起,如果我们可以暂时使用现有的 C/汇编代码,我们认为没有任何理由立即重新发明轮子一些时尚。
最佳答案
其实很简单,甚至不需要反射(reflection)。
[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
我已经写了一篇关于这个的博文:https://esozbek.me/inline-assembly-in-csharp-and-dotnet/
关于c# - 在 C# 中使用 C/内联汇编,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18836120/