[英]Calling C DLL from C++ gives Access Violation but C# project with DllImport working
我有一個32位的第三方C DLL,我需要集成,但我遇到了一個難以理解/追蹤的錯誤。
我可以編譯並成功鏈接一個簡單的C ++ 32位應用程序,該應用程序包含以下內容:
#include "stdafx.h"
#include <windows.h>
extern "C" int __stdcall external_method(int cardno);
int main()
{
int n = external_method(0);
return 0;
}
當我嘗試在調試模式下運行應用程序時,它提供以下內容:
Unhandled exception at 0x100AADF5 (ExternalModule.dll) in
ConsoleApplication2.exe: 0xC0000005: Access violation reading location 0x00000000.
但是,如果我創建一個使用DllImport / PInvoke調用相同函數的簡單C#應用程序,它運行正常:
namespace ConsoleApplication3
{
class Program
{
[DllImport("ExternalModule.dll")]
public static extern int external_method(int n);
static void Main(string[] args)
{
external_method(0);
Debug.WriteLine("YES!");
}
}
}
我很難理解一個人如何工作而另一個人失敗了。 不幸的是我無法訪問C DLL的開發人員。
任何幫助非常感謝。
更新感謝您的評論。 以下是該方法的頭文件條目:
int __stdcall exernal_method(int cardno);
可以肯定的是,調用約定是可以的。 正在加載DLL,因為使用DLL的調試版本我可以看到它在失敗之前將一些消息輸出到調試輸出。
這可能是退出方法時堆棧被破壞的問題嗎? 我嘗試了幾種不同的調用約定,但這是鏈接器能夠使用的唯一一種。
堆棧損壞不太可能。
一個可能的原因是不同的DLL加載方法。 您的C ++應用程序靜態加載它(Windows在啟動進程之前加載您的DLL),C#動態加載(CLR在進程開始運行后加載DLL)。 要測試此假設,請從鏈接器中刪除ExternalModule.lib,將C ++代碼更改為調用LoadLibrary和GetProcAddress。
另一個可能的原因是C#運行時初始化COM,C ++應用程序沒有,並且您的DLL嘗試使用COM。 在您的C ++應用程序中,嘗試在exernal_method之前添加CoInitialize [Ex]。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.