【问题标题】:Calling C++ DLL from C# is ok under Windows 7 but fails under Windows 10在 Windows 7 下从 C# 调用 C++ DLL 可以,但在 Windows 10 下失败
【发布时间】:2016-12-28 14:15:31
【问题描述】:

我的程序从我的 C# 程序调用一个 C++ DLL。

问题是生成的可执行文件在 Windows 7 下运行良好,但在 Windows 10 下不运行!?

步骤如下:

我使用 64 位的 g++(TDM-GCC-64)编译我的 C++ DLL。 我使用 Visual Studio 15 编译我的 C# 程序并以 64 位为目标 .NET 框架 4.5.2。

C++ DLL 代码是:

main.h

#ifndef __MAIN_H__
#define __MAIN_H__

#include <windows.h>

/*  To use this exported function of dll, include this header in your project.  */

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif


#ifdef __cplusplus
extern "C"
{
#endif

void DLL_EXPORT SomeFunction(const LPCSTR sometext);

#ifdef __cplusplus
}
#endif

#endif // __MAIN_H__

main.cpp

#include "main.h"
#include <iostream>

// a sample exported function
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
    std::cout << "TEST FROM DLL : " << sometext << std::endl;
}

构建命令是: C:\TDM-GCC-64\bin\g++ -shared -o ..\TestDllCall\bin\x64\Debug\myDLL.dll -m64 -g -D BUILD_DLL -L。 main.cpp

可以看到,dll是直接在c#测试程序的target目录下创建的(Debug in 64 bits)。

C#主程序是:

程序.cs

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace TestHstLibrary
{
    class MainProg
    {
        static void Main(string[] args)
        {
            ProgramTest ProgramTest = new ProgramTest();
            ProgramTest.dllCall();
            Console.ReadKey();
        }
    }

    class ProgramTest
    {
        [DllImport("myDLL.dll", EntryPoint = "SomeFunction")]
        static extern void SomeFunction(string sometext);

        public ProgramTest() {            
        }

        public void dllCall()
        {
            Console.WriteLine("dllCall ... ");            
            try
            {
                SomeFunction("Hello !");
            } catch (Exception e)
            {
                Console.WriteLine("EXCEPTION : " + e.Message);
                Console.WriteLine(e.ToString());
            }
            Console.WriteLine("");
        }        
    }
}

注意:构建是在最终目标平台上完成的:Win10 64bits。

在我的 Windows 10 上运行,我有以下内容:

dll调用 ...
异常:无法加载 DLL“myDLL.dll”:动态链接库 (DLL) 初始化例程失败。 (来自 HRESULT 的异常:0x8007045A) System.DllNotFoundException:无法加载 DLL“myDLL.dll”:动态链接库 (DLL) 初始化例程失败。 (HRESULT 异常:0x8007045A) à ProgramTest.SomeFunction(String sometext) à ProgramTest.dllCall() dans C:\TestDllCall\TestDllCall\Program.cs:ligne 30

将整个build目录从Win10拷贝到Win7之后, 在我的 Win7 上运行它,我有以下内容:

dll调用...
从 DLL 进行测试:您好!

一切正常。

如果有人知道为什么它在 Win10 下失败而不是在 Win7 下失败,我将很高兴得到答案。

我检查了dependency walker,结果如下: - 在Windows 10下,即使在Win10下已经生成,也缺少一些依赖 - 在Windows 7下,所有依赖都ok。

所以我尝试使用来自 G++ 的 TDM-GCC-64 的其他 c++ 编译器,我使用来自 cygwin 的编译器进行了测试:没有给出更好的结果,甚至更糟。

我还尝试将我的 c# 字符串参数作为 IntPtr 传递,如下所示:

IntPtr myptr = Marshal.StringToHGlobalAnsi("Hello !");
SomeFunction(myptr);

但是在Win10下还是不行,但是在Win7下还是可以的。

另一个测试是从我的 dll 中删除 std::cout,最后调用没问题,但我仍然想让它工作,因为这是在测试环境和生产环境中,我必须使用一个我没有源代码的外部 dll。

【问题讨论】:

  • 在将应用程序移动到 Win10 时,您没有忘记将 dll 复制到正确的位置,是吗?
  • 欢迎来到 Stack Overflow。请花时间阅读The Tour 并参考Help Center 中的材料,您可以在这里问什么以及如何问。
  • 我在目标平台Win10 64bits下构建。一切都在同一个目录中。然后在 Windows7 下进行测试,我复制了目录及其内容。
  • 您的 dll 已找到,但其初始化代码失败。也许缺少一个依赖项(比如找不到 libstdc++),所以检查一下。
  • 微软的事件查看器(运行 eventvwr)会告诉你更多。转到“Windows 日志”>“应用程序”并找到您的特定 .dll 错误。这可能是缺少依赖项或并行错误。如果您在将错误事件添加到您的问题时对我发表评论,我会尽力提供进一步的帮助。

标签: c# c++ dll language-interoperability


【解决方案1】:

我更新了如下代码:

int DLL_EXPORT SomeFunction()
{
    return 5;
}

它正在工作。从 c# 调用非托管 dll 就可以了。

之后,我搜索了 cout,我在 stackoverflow 中找到了一些与 c# 调用的非托管 dll 中 cout 的用法相关的主题...

所以在我再次将功能更改为以下内容后:

void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
    MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
}

错误再次发生!

然后我在尝试解决这个问题的过程中听取了一些建议后决定使用 Visual Studio C++(而不是 TDM-GCC-64)构建 DLL。

使用 MS C++ 构建 DLL 并在 Win10 下运行测试后:它正在工作:-)

std::cout 没问题 消息框没问题 不再有:HRESULT 异常:0x8007045A

非常感谢回答的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-28
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多