在Windows 7下从C#调用C ++ DLL是正常的,但在Windows 10下失败

时间:2016-12-28 14:15:31

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

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

问题是生成的可执行文件在Windows 10下运行的是undex,但在Windows 10下却没有!?

步骤如下:

我用64位的g ++(TDM-GCC-64)编译我的C ++ DLL。 我使用Visual Studio 15编译我的C#程序,并以64位编译.NET Framework 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#test程序的目标目录中创建的(64位调试)。

C#主程序是:

Program.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 64位。

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

  

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

将整个构建目录从Win10复制到Win7后, 在我的Win7上运行它,我有以下内容:

  

dllCall ...
  从DLL测试:你好!

工作正常。

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

我检查依赖性walker并具有以下内容: - 在Windows 10下,即使在Win10下生成了某些依赖项,也会丢失一些依赖项 - 在Windows 7下,所有依赖项都可以。

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

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

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

但它在Win10下无效,但仍在Win7下工作。

另一个测试是删除std :: cout形式我的dll,最后调用是好的,但我仍然想让它工作,因为这是在测试环境和生产环境中我将不得不使用它一个我没有源代码的外部DLL。

1 个答案:

答案 0 :(得分:0)

我更新了以下代码:

int DLL_EXPORT SomeFunction()
{
    return 5;
}

它正在运作。所谓的来自c#的非托管dll就可以了。

之后,我搜索了一下cout,我在stackoverflow中发现了一些与c#在非托管dll中的使用有关的话题,从c#中调用...

所以在我再次将函数更改为以下内容之后:

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没问题 messageBox没问题 没有更多:HRESULT的异常:0x8007045A

非常感谢回答的人。