Search code examples
c#c++dllpinvokedllimport

Can only use 1/4 functions from C++ DLL in C# application


Having a bit of trouble converting a C++ DLL for use in C#.

It is working.. The first C++ function in the DLL which is just: int subtractInts(int x, int y) and its typical body works no problem. All of the other functions are as simple and have been tested. However, I have been following a tutorial and doing some funky stuff to use that code in C# as a C++ DLL (for portability).

My steps are:

• Create a C++ class, test it and save it – only using the ‘class.cpp’ and ‘class.h’ files • Create a Win32 library project in Visual Studio 2010, choose DLL on start up and for each function I want to expose to C#.. the below code

extern "C" __declspec(dllexport) int addInts(int x, int y)
extern "C" __declspec(dllexport) int multiplyInts(int x, int y)
extern "C" __declspec(dllexport) int subtractInts(int x, int y)
extern "C" __declspec(dllexport) string returnTestString()

Pretty key point, that is the order I externed them in my DLL.

Then as a test because I did have this problem before.. I referenced them in a different way in my C# project

   [DllImport("C:\\cppdll\\test1\\testDLL1_medium.dll", CallingConvention = CallingConvention.Cdecl)]

    public static extern int subtractInts(int x, int y);
    public static extern int multiplyints(int x, int y);
    public static extern int addints(int x, int y);
    public static extern string returnteststring();

The ONLY function that work when called from C# is subtractInts, which is obviously the function referenced first. All others cause errors (see below) on compilation.

If I don't comment out that above code and go to externally reference all of those functions. I get the following error at multipyInts(int x, int y).

Could not load type 'test1DLL_highest.Form1' from assembly 'test1DLL_highest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because the method 'multiplyints' has no implementation (no RVA).

I would imagine that sorting that would sort everything.

Cheers.


Solution

  • You need to add the DllImportAttribute to all four methods, remove the paths, and fix your casing:

    [DllImport("testDLL1_medium.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int subtractInts(int x, int y);
    [DllImport("testDLL1_medium.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int multiplyInts(int x, int y);
    [DllImport("testDLL1_medium.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int addInts(int x, int y);
    [DllImport("testDLL1_medium.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern string returnTestString();
    

    Also make sure that the native DLL is in the same location as your managed assembly (or discoverable via normal DLL discovery methods).