Making DLL class which is a wrapper for another class

Feb 29, 2012 at 6:56pm
I have created a DLL in C++ which I want to use in a C# app. I tested the C++ code in a standalone C++ program before I converted it to a DLL and it all worked fine, now that I am trying to call it externally however it is behaving nothing like it did in those tests so I think maybe I have exported the DLL incorrectly.

In my DLL project I have a DLL header file and source file, stdafx.h, and the header and source file of the C++ class I want to export. The DLL header looks like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef DLL_WRAPPER
#define DLL_WRAPPER

#include "stdafx.h"
#include <windows.h>
#include "VGSLib.h"

extern "C"{
	__declspec(dllexport) DWORD __stdcall Init(char* info[], int amount, int ID1, int ID2);
	__declspec(dllexport) DWORD __stdcall GetValues(SValStruct* vs, DWORD flag=kiNOOVERRIDE);
	__declspec(dllexport) DWORD __stdcall GetNums(int amount, int* out, DWORD flag=kiNOOVERRIDE);
	__declspec(dllexport) DWORD __stdcall GetWV(SWVStruct* wv, int ID, DWORD amount, DWORD flag=kiNOOVERRIDE);
        __declspec(dllexport) DWORD __stdcall Confirm(bool *bConfirmed, int ID, DWORD flag=kiNOOVERRIDE);
	__declspec(dllexport) bool __stdcall Formatted();
	__declspec(dllexport) LPWSTR __stdcall GetErrorString(int code);
}

#endif 


kiNOOVERRIDE is declared in VGSLib.h, as are SWVStruct and SValStruct. The cpp file conatins an instance of the class and just calls the functions and returns whatever value the called function returns, as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "stdafx.h"
#include "DLLWrapper.h"
#include "VGSLib.h"

VGSLib* pVGSLib;

__declspec(dllexport) DWORD __stdcall Init(char* info[], int amount, int ID1, int ID2){
	pVGSLib = new VGSLib();
	if ( pVGSLib ){
		return pVGSLib->Init(info, amount, ID1, ID2);
	}

	return -1;
}

__declspec(dllexport) DWORD __stdcall GetValues(SValStruct* vs, DWORD flag){
	if ( pVGSLib ){
		return pVGSLib->GetValues(vs,flag);
	}

	return -1;
}

__declspec(dllexport) DWORD __stdcall GetNums(int amount, int* out, DWORD flag){
	if ( pVGSLib ){
		return pVGSLib->GetNums(amount,out,flag);
	}

	return -1;
}

__declspec(dllexport) DWORD __stdcall GetWV(SWVStruct* wv, int ID, DWORD amount, DWORD flag){
	if ( pVGSLib ){
		return pVGSLib->GetWV(wv,ID,amount,flag);
	}

	return -1;
}

__declspec(dllexport) DWORD __stdcall Confirm(bool *bConfirmed, int ID, DWORD flag){
	if ( pVGSLib ){
		return pVGSLib->Confirm(bConfirmed,ID,flag);
	}

	return -1;
}

__declspec(dllexport) bool __stdcall Formatted(){
	if ( pVGSLib ){
		return pVGSLib->Formatted();
	}

	return false;
}

__declspec(dllexport) LPWSTR __stdcall GetErrorString(int code){
	if ( pVGSLib ){
		return pVGSLib->GetErrorString(code);
	}

	return (LPWSTR)"pVGSLib instance does not exist - did you call Init()?";
}


My code to test this in C# is this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace DLLTest
{
    class Program
    {       
        [DllImport("DLLWrapper.dll")]
        public static extern DWORD Init(ref char[] info, int amount, int ID1, int ID2);
                
        static void Main(string[] args)
        {
            string[] info = new string[3];
            info[0] = "blahblahblah";
            info[1] = "bloobloobloo";
            info[2] = "F";
            int result = -1;
            result = Init(info, 1, 16, 200);
        }
    }
}


It loads the DLL fine, and I know the VGSLib class works fine,, is there something wrong with the way I've made the wrapper class? Is it ok to have a global instance of the class in DLLWrapper.cpp? Also, I also wasn't sure how to send in an array of char*s to the Init function from C#, is the way I've done it correct? I've tested simpler functions too like GetErrorString and they also aren't working so that's not the main cause of my problem.

Thanks.
Jnr.
Last edited on Feb 29, 2012 at 6:57pm
Feb 29, 2012 at 7:28pm
closed account (o1vk4iN6)
It works fine for C++ cause it uses a library file, you need to export the name of the function as C# doesn't have access to it and uses one of microsoft's functions to get a function using a string. Using visual studio it's a ".def" file inwhich you specify the names of the functions you want to export. Not sure about any other compiler.


You also have a potential memory leak:

1
2
3
4
pVGSLib = new VGSLib();
	if ( pVGSLib ){
		return pVGSLib->Init(info, amount, ID1, ID2);
	}
Last edited on Feb 29, 2012 at 7:30pm
Feb 29, 2012 at 7:39pm
Ah yes I'll have to sort that out.

you need to export the name of the function as C# doesn't have access to it

What function are you referring to here? Do you mean I need to export every windows function that I use in the VGSLib class? I included <windows.h> in the DLLWrapper class so I thought the DLL would have access to the Windows functions.
Feb 29, 2012 at 9:17pm
bump?
Topic archived. No new replies allowed.