【问题标题】:Calling C DLL from C++ gives Access Violation but C# project with DllImport working从 C++ 调用 C DLL 会导致访问冲突,但 C# 项目与 DllImport 工作
【发布时间】:2026-01-16 02:00:01
【问题描述】:

我有一个需要集成的 32 位第 3 方 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 的开发人员。

非常感谢任何帮助。

更新感谢 cmets。这是该方法的头文件条目:

int __stdcall exernal_method(int cardno);

我有理由确定调用约定是可以的。正在加载 DLL,因为使用 DLL 的调试版本,我可以看到它在失败之前向调试输出输出了一些消息。

在退出方法时堆栈被损坏可能是一个问题吗?我尝试了几种不同的调用约定,但这是链接器能够使用的唯一一种。

【问题讨论】:

  • 不是 C# 用户,但可能是调用约定不匹配?
  • 你的 C# 和你的 C 代码没有区别。您将不得不寻找环境原因。还有一个电话号码。
  • 会不会是您的 C++ 程序找不到 DLL 或找到不同的版本?链接器可能只是链接到一个导入库,所以它不会抱怨。
  • 调试器或者它没有发生

标签: c++ c dll


【解决方案1】:

堆栈损坏的可能性不大。

一个可能的原因是不同的 DLL 加载方法。您的 C++ 应用程序静态加载它(Windows 在进程启动之前加载您的 DLL),C# 动态加载(CLR 在进程开始运行后加载 DLL)。要验证这个假设,请从链接器中删除 ExternalModule.lib,将您的 C++ 代码更改为调用 LoadLibrary 和 GetProcAddress。

另一个可能的原因是 C# 运行时初始化 COM,而 C++ 应用程序没有初始化,并且您的 DLL 尝试使用 COM。在您的 C++ 应用程序中,尝试在您的 exernal_method 之前添加 CoInitialize[Ex]。

【讨论】:

  • 这是第二个原因!谢谢
  • @jugglingcats 不客气。也不要忘记 CoUninitialize。通常应该在线程退出之前完成。
最近更新 更多