Моя программа вызывает C ++ DLL из моей программы на C #.
Проблема в том, что сгенерированный исполняемый файл работает под управлением ОС Undex 7, но не под Windows 10!?
Шаги перечислены ниже:
Я компилирую мою C ++ DLL, используя g ++ (из TDM-GCC-64) в 64 битах.
Я компилирую свою программу на C # с использованием Visual Studio 15 и целевой платформы .NET 4.5.2 в 64 битах.
Код 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;
}
Команда построения:
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 #:
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 …
ИСКЛЮЧЕНИЕ: Невозможно загрузить 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
После копирования всего каталога сборки из Win10 в Win7,
запустить его на моем Win7, у меня есть следующее:
dllCall …
ТЕСТ ИЗ DLL: Привет!
Работает нормально.
Если у кого-то есть идея, почему он не работает под Win10, а не под Win7, я буду рад получить ответ.
Я проверяю с помощью Walker зависимости и имел следующее:
— В Windows 10 некоторые зависимости отсутствуют, даже если они были созданы под Win10
— Под Windows 7 все зависимости в порядке.
Поэтому я пытаюсь использовать другой компилятор c ++ из g ++ TDM-GCC-64, который я тестировал вместе с компилятором cygwin: не дает лучшего результата, даже хуже.
Я также пытаюсь передать мой строковый параметр c # как IntPtr, как показано ниже:
IntPtr myptr = Marshal.StringToHGlobalAnsi("Hello !");
SomeFunction(myptr);
Но это не работает ни под Win10, но все еще работает под Win7.
Другой тест состоял в том, чтобы удалить std :: cout из моей dll, наконец, вызов в порядке, но я все еще хочу заставить его работать, как это происходит в тестовой среде, и в производственной среде мне придется сделать это с внешней dll который у меня нет исходного кода.
Я обновил код, как показано ниже:
int DLL_EXPORT SomeFunction()
{
return 5;
}
Это работало. Так называемый неуправляемый DLL из C # в порядке.
После того, как я ищу cout, я нашел в stackoverflow некоторую тему, связанную с использованием cout в неуправляемой dll, вызываемой из c # …
Поэтому после того, как я снова изменил функцию на следующую:
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
}
Ошибка повторяется!
Тогда я решил после некоторых советов, пока решал эту проблему, построить DLL с помощью Visual Studio C ++ (вместо TDM-GCC-64).
После сборки DLL с MS C ++ и запуска теста под Win10: Это работает 🙂
С std :: cout все в порядке
MessageBox в порядке
Больше нет: Исключение из HRESULT: 0x8007045A
Большое спасибо людям, которые ответили.
Других решений пока нет …