Yoh*_*anu 5 c# unmanaged marshalling dllimport
我目前正在导出 Win32 应用程序的一些函数,以便从托管代码中调用它,但我陷入了 AccessViolationException。它是一个非常简单的 DllImport,具有简单的类型,但是一旦我在非托管应用程序中调用诸如 malloc 或 printf 之类的函数,它就会抛出异常。
这是代码示例: //C# 程序
static void Main(string[] args)
{
uint result = MyClass.ExecuteCommand((byte)10);
Console.WriteLine(result);
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
//C#类库
public const string AppicationExe= "Application.exe";
[DllImport(AppicationExe, EntryPoint = "ExecuteCommand")]
public static extern UInt32 ExecuteCommand(byte mybyte);
Run Code Online (Sandbox Code Playgroud)
// C 应用程序
__declspec(dllexport) UINT32 __stdcall ExecuteCommand(unsigned char mybyte)
{
printf("Why is it so difficult to make it works !!!!!!");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
托管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”项目符号。
| 归档时间: |
|
| 查看次数: |
1718 次 |
| 最近记录: |