我目前正在尝试导出Win32应用程序的一些函数,以便从托管代码中调用它,我陷入了AccessViolationException。这是一个非常简单的DllImport,只有简单的类型,但只要在非托管应用程序中调用malloc或printf之类的函数,就会抛出异常。
以下是代码示例: // C#Program
static void Main(string[] args)
{
uint result = MyClass.ExecuteCommand((byte)10);
Console.WriteLine(result);
Console.ReadLine();
}
// C#类库
public const string AppicationExe= "Application.exe";
[DllImport(AppicationExe, EntryPoint = "ExecuteCommand")]
public static extern UInt32 ExecuteCommand(byte mybyte);
// C Application
__declspec(dllexport) UINT32 __stdcall ExecuteCommand(unsigned char mybyte)
{
printf("Why is it so difficult to make it works !!!!!!");
return 0;
}
答案 0 :(得分:3)
托管 DLL与EXE之间的非常差别不大。您可以将类库的程序集重命名为* .exe,程序仍然有效。
然而,对于C程序来说,不是的情况。 EXE与DLL有很大不同。首先,C程序要求始终在main()函数中启动代码。需求是因为在C程序开始运行之前,必须首先初始化C运行时库。必须在开始执行托管代码之前初始化CLR的粗略等价物。像你一样跳过初始化很可能在程序使用C运行时函数时崩溃。喜欢printf()。
完全不是托管代码中的问题,因为CLR在执行程序之前总是先被初始化。
另一个非常重要的细节是,非托管EXE通常由链接器优化,尽管它们正在消失。可执行文件通常具有重定位表,当程序加载到与其请求的基址不同的地址时,需要调整的地址列表。始终需要DLL,因为加载地址不可预测,地址可能已在使用中。 EXE不需要,因为它总是加载到可预测的地址,因此链接器会剥离该表以使文件更小。 Kaboom如果程序实际上 被加载到错误的地址,那么当你进行pinvoke时它总会出现。
由于抖动,托管代码完全没有问题。
您需要创建一个DLL。在Visual Studio中轻松使用项目向导。选择Win32 Project项目模板,然后选择" DLL"下一个向导步骤中“应用程序类型”设置的项目符号。