簡體   English   中英

從C ++調用C DLL會產生訪問沖突,但C#項目與DllImport一起工作

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM