V
V
Vladimir Vladimirovich2017-05-29 00:28:42
C++ / C#
Vladimir Vladimirovich, 2017-05-29 00:28:42

How to solve the problem with dll?

Created a win32 project with CUDA. Compile successfully dll. But when trying to connect it in c#, it gives an error:
"Unhandled exception of type 'System.BadImageFormatException' in mscorlib.dll
Additional information: Failed to load file or assembly 'myDLL' or one of its dependencies. The module was expected to contain an assembly manifest."
library codes:
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;
}

and finally myDLL.def
LIBRARY myDLL
EXPORTS
cudaCard
LoadDll
UnloadDll
Card

library call (put the myDLL file in the debug folder of the c# project)
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");

Answer the question

In order to leave comments, you need to log in

2 answer(s)
T
tomatho, 2017-05-29
@tomatho

The matter is that at you in a C ++ so-called unmanaged code.
The easiest way to call it is something like this:

using System.Runtime.InteropServices;

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

In this case, Assembly.Load is not needed. Because it is for managed. Reflection seems to hint.
You can also wrap it in C ++ so that it becomes managed, but this is better than Google.
The margins of these answers are too narrow to accommodate this, and I don't know the details either.
Until I forgot: the bitness of the dll must match the bitness of the application.
MSDN says that System.BadImageFormatException can occur if /fixed:no is not specified when compiling.

S
Sumor, 2017-05-29
@Sumor

The bitness of the library must match.
Connection via DllImport. In this case, the structures used will need to be rewritten in C # so that they can be used.
C++ types in a function or structure description are described with marshaling attributes - for automatic conversion to C# types. In particular, you use char - it's an 8-bit character, C# uses Unicode - 2 characters. For automatic translation to Unicode, you need to specify the Charset parameter.

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);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question