[英]Calling C++ DLL from C# is ok under Windows 7 but fails under Windows 10
My program calls a C++ DLL from my C# program. 我的程序从C#程序调用C ++ DLL。
The problem is that the generated executable is running fine undex Windows 7 but not under Windows 10 !? 问题在于生成的可执行文件在Windows 7上运行良好的undex,但在Windows 10下却没有运行!
The steps are listed below: 步骤如下:
I compile my C++ DLL using g++ (of TDM-GCC-64) in 64 bits. 我使用64位的(TDM-GCC-64)g ++编译我的C ++ DLL。 I compile my C# program using Visual studio 15 and target .NET framework 4.5.2 in 64 bits.
我使用Visual Studio 15和目标.NET Framework 4.5.2(64位)编译C#程序。
The C++ DLL code is : C ++ DLL代码为:
#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__
#include "main.h"
#include <iostream>
// a sample exported function
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
std::cout << "TEST FROM DLL : " << sometext << std::endl;
}
The build command is : C:\\TDM-GCC-64\\bin\\g++ -shared -o ..\\TestDllCall\\bin\\x64\\Debug\\myDLL.dll -m64 -g -D BUILD_DLL -L. 构建命令是:C:\\ TDM-GCC-64 \\ bin \\ g ++ -shared -o .. \\ TestDllCall \\ bin \\ x64 \\ Debug \\ myDLL.dll -m64 -g -D BUILD_DLL -L。 main.cpp
main.cpp
You can notice that the dll is created directly in the target directory of the c# test program (Debug in 64 bits). 您会注意到,dll是直接在c#测试程序的目标目录中创建的(以64位调试)。
The C# main program is: C#主程序是:
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("");
}
}
}
Note : The build is done on the final target plateform : Win10 64bits. 注意:构建是在最终目标平台:Win10 64bits上完成的。
Running on my Windows 10, I have the following : 在Windows 10上运行,我具有以下功能:
dllCall ...
dllCall ...
EXCEPTION : Unable to load DLL 'myDLL.dll': A dynamic link library (DLL) initialization routine failed.例外:无法加载DLL'myDLL.dll':动态链接库(DLL)初始化例程失败。 (Exception from HRESULT : 0x8007045A) System.DllNotFoundException: Unable to load DLL 'myDLL.dll': A dynamic link library (DLL) initialization routine failed.
(来自HRESULT的异常:0x8007045A)System.DllNotFoundException:无法加载DLL“ myDLL.dll”:动态链接库(DLL)初始化例程失败。 (Exception de HRESULT : 0x8007045A) à ProgramTest.SomeFunction(String sometext) à ProgramTest.dllCall() dans C:\\TestDllCall\\TestDllCall\\Program.cs:ligne 30
(HRESULT异常:0x8007045A)àProgramTest.SomeFunction(字符串sometext)àProgramTest.dllCall()dans C:\\ TestDllCall \\ TestDllCall \\ Program.cs:ligne 30
After a copy of the entire build directory from Win10 to a Win7, running it on my Win7, I have the following : 从Win10到Win7的整个构建目录的副本,在Win7上运行它后,我有以下内容:
dllCall ...
dllCall ...
TEST FROM DLL : Hello !从DLL测试:您好!
It's working fine. 一切正常。
If someone has an idea why it fails under Win10 and not under Win7, I will be pleased to have the answer. 如果有人知道为什么它会在Win10而不是Win7下失败,我将很高兴得到答案。
I check with dependency walker and had the following: - Under Windows 10, some dependencies are missing even if it has been generated under Win10 - Under Windows 7, all dependencies are ok. 我检查了依赖关系检查程序,发现以下内容:-在Windows 10下,即使已在Win10下生成某些依赖关系,也没有-在Windows 7下,所有依赖关系都可以。
So I try with an other c++ compiler from g++ of TDM-GCC-64, I tested with the one from cygwin : does not give a better result, even worse. 因此,我尝试使用TDM-GCC-64的g ++的其他c ++编译器,并使用cygwin的c:进行了测试:不会给出更好的结果,甚至更糟。
I also try to pass my c# string parameter as a IntPtr as shown below: 我也尝试将c#字符串参数作为IntPtr传递,如下所示:
IntPtr myptr = Marshal.StringToHGlobalAnsi("Hello !");
SomeFunction(myptr);
But it does not work either under Win10 but still working under Win7. 但是它既不能在Win10下工作,也可以在Win7下工作。
An other test was to remove the std::cout form my dll, finally the call is ok but I still want to make it work as this is in a test environment and in a production environment I will have to make it with an external dll which I don't have the source code. 另一个测试是从我的dll中删除std :: cout,最后的调用是可以的,但是我仍然想使它工作,因为它是在测试环境中和生产环境中,我将不得不使用一个外部dll来使其正常工作我没有源代码。
I updated the code as below : 我更新了如下代码:
int DLL_EXPORT SomeFunction()
{
return 5;
}
It was working. 它正在工作。 So called unmanaged dll from c# is ok.
从C#调用非托管dll是可以的。
After, I search about the cout, I found in stackoverflow some topic related to usage of cout in unmanaged dll called from c# ... 之后,我搜索了cout,在stackoverflow中发现了一些与cout在c#中调用的非托管dll中的cout用法有关的主题。
So after I changed again the function to the following : 因此,在我再次将功能更改为以下内容之后:
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
}
The error happens again ! 错误再次发生!
Then I decided after some advice while triyng to solve this problem to build the DLL with Visual Studio C++ (instead of TDM-GCC-64). 然后,我在寻求建议的同时决定解决该问题,以使用Visual Studio C ++(而不是TDM-GCC-64)构建DLL。
After building the DLL with MS C++ and running the test under Win10: It's working :-) 用MS C ++构建DLL并在Win10下运行测试后::)
The std::cout is OK The messageBox is OK There is no more : Exception from HRESULT : 0x8007045A std :: cout正常运行messageBox正常运行没有更多:HRESULT异常:0x8007045A
Thanks a lot to people who answered. 非常感谢回答的人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.