簡體   English   中英

在Windows 7下從C#調用C ++ DLL可以,但在Windows 10下失敗

[英]Calling C++ DLL from C# is ok under Windows 7 but fails under Windows 10

我的程序從C#程序調用C ++ DLL。

問題在於生成的可執行文件在Windows 7上運行良好的undex,但在Windows 10下卻沒有運行!

步驟如下:

我使用64位的(TDM-GCC-64)g ++編譯我的C ++ DLL。 我使用Visual Studio 15和目標.NET Framework 4.5.2(64位)編譯C#程序。

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__

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#測試程序的目標目錄中創建的(以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 64bits上完成的。

在Windows 10上運行,我具有以下功能:

dllCall ...
例外:無法加載DLL'myDLL.dll':動態鏈接庫(DLL)初始化例程失敗。 (來自HRESULT的異常:0x8007045A)System.DllNotFoundException:無法加載DLL“ myDLL.dll”:動態鏈接庫(DLL)初始化例程失敗。 (HRESULT異常:0x8007045A)àProgramTest.SomeFunction(字符串sometext)àProgramTest.dllCall()dans C:\\ TestDllCall \\ TestDllCall \\ Program.cs:ligne 30

從Win10到Win7的整個構建目錄的副本,在Win7上運行它后,我有以下內容:

dllCall ...
從DLL測試:您好!

一切正常。

如果有人知道為什么它會在Win10而不是Win7下失敗,我將很高興得到答案。

我檢查了依賴關系檢查程序,發現以下內容:-在Windows 10下,即使已在Win10下生成某些依賴關系,也沒有-在Windows 7下,所有依賴關系都可以。

因此,我嘗試使用TDM-GCC-64的g ++的其他c ++編譯器,並使用cygwin的c:進行了測試:不會給出更好的結果,甚至更糟。

我也嘗試將c#字符串參數作為IntPtr傳遞,如下所示:

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

但是它既不能在Win10下工作,也可以在Win7下工作。

另一個測試是從我的dll中刪除std :: cout,最后的調用是可以的,但是我仍然想使它工作,因為它是在測試環境中和生產環境中,我將不得不使用一個外部dll來使其正常工作我沒有源代碼。

我更新了如下代碼:

int DLL_EXPORT SomeFunction()
{
    return 5;
}

它正在工作。 從C#調用非托管dll是可以的。

之后,我搜索了cout,在stackoverflow中發現了一些與cout在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正常運行messageBox正常運行沒有更多:HRESULT異常:0x8007045A

非常感謝回答的人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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