Как решить проблему с dll?

Создал проект win32 c CUDA. Компилирую успешно dll. Но при попытке подключить его в c# выдаёт ошибку:
" Необработанное исключение типа "System.BadImageFormatException" в mscorlib.dll

Дополнительные сведения: Не удалось загрузить файл или сборку "myDLL" либо одну из их зависимостей. Ожидалось, что модуль содержит манифест сборки."

коды библиотеки:
myDLL.cpp
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <assert.h>
#include <string>
#include <cuda_runtime.h>
#include <helper_functions.h>
#include <helper_cuda.h>
#include "myDLL.h"

using namespace std;

typedef struct {

	DWORD  mVersion; //!< mIRC Version
	HWND   mHwnd;    //!< mIRC Hwnd
	BOOL   mKeep;    //!< mIRC variable stating to keep DLL in memory

} LOADINFO;

typedef struct {

	HANDLE m_hFileMap; //!< Handle to the mIRC DLL File Map
	LPSTR m_pData;     //!< Pointer to a character buffer of size 900 to send mIRC custom commands
	HWND m_mIRCHWND;   //!< mIRC Window Handle

} mIRCDLL;


mIRCDLL mIRCLink;


void WINAPI LoadDll(LOADINFO * load) {
	mIRCLink.m_hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, 4096, "mIRC");
	mIRCLink.m_pData = (LPSTR)MapViewOfFile(mIRCLink.m_hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	mIRCLink.m_mIRCHWND = load->mHwnd;
}

int WINAPI UnloadDll(int timeout) {

	// DLL unloaded because mIRC exits or /dll -u used
	if (timeout == 0) {
		UnmapViewOfFile(mIRCLink.m_pData);
		CloseHandle(mIRCLink.m_hFileMap);
		return 1;
	}
	// Keep DLL In Memory
	else
		return 0;
}

int __declspec(dllexport) __stdcall cudaCard(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause) {
	int nDevices;
	string str = "";

	cudaGetDeviceCount(&nDevices);
	for (int i = 0; i < nDevices; i++) {
		cudaDeviceProp prop;
		cudaGetDeviceProperties(&prop, i);
		str = str + prop.name + " @";
	}
	char *cstr = &str[0u];
	strcpy(data, cstr);
	return 3;
}
int __declspec(dllexport) __stdcall Card() {
	return 3;
}

и наконец myDLL.def
LIBRARY myDLL
EXPORTS
cudaCard
LoadDll
UnloadDll
Card

вызов библиотеки (положил файл myDLL в дебаг-папку проекта с#)
Assembly a = Assembly.Load("myDLL");// здесь и ошибка
            Object o = a.CreateInstance("vscode");
            Type t = a.GetType("vscode");

            Object[] numbers = new Object[2];
            numbers[0] = 2;
            numbers[1] = 3;
            MethodInfo mi = t.GetMethod("Card");
  • Вопрос задан
  • 2675 просмотров
Пригласить эксперта
Ответы на вопрос 2
@tomatho
Дело в том, что у тебя в C++ так называемый unmanaged code.
Проще всего его вызвать как-то так:
using System.Runtime.InteropServices;

[DllImport("myDll.dll", CallingConvention=CallingConvention.StdCall)]
public static extern int Card();

При этом Assembly.Load не нужен. Потому что он для managed. Reflection как бы намекает.
Можно ещё обернуть в C++ так чтобы он стал managed, но это лучше гугл.
Поля этих ответов слишком узкие чтобы это вместить, да и я не знаю деталей.

Пока не забыл: битность dll должна совпадать с битностью приложения.

В MSDN написано, что System.BadImageFormatException может быть если не указан /fixed:no при компиляции.
Ответ написан
Комментировать
@Sumor
Битность библиотеки должна совпадать.

Подключение через DllImport. При этом используемые структуры нужно будет переописать в C#, чтобы ими можно было пользоваться.
С++ типы в описании функции или структуры описываются с атрибутами маршалинга - для автоматического перевода в типы C#. В частности, ты используешь char - это 8-битный символ, в C# используется Unicode - 2 символа. Для автоматического перевода в Unicode нужно указывать параметр Charset.
using System.Runtime.InteropServices;

[DllImport("myDll.dll", CallingConvention=CallingConvention.StdCall)]
public static extern int Card();

[DllImport("myDll.dll", CallingConvention=CallingConvention.StdCall, Charset=Charset.Ansi)]
public static extern int cudaCard(IntPtr mWnd, IntPtr aWnd, string data, string parms, bool show, bool nopause);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы