views:

41

answers:

2

Hi all, this is my first post.

I have a native function inside a managed (c++/cli) mixed-mode library that calls a seperate native dll.

Here is the native function that initializes some function pointers using windows GetProcAdress:

//in header
static HMODULE hDll;
static void (*MYDLL_Func1)(void*);
static void (*MYDLL_Func2)(void);

int BeginDll()
{
    if (!hDll) {
        hDll= LoadLibraryHelper("mydll.dll");
        if (hDll) {
            MYDLL_Func1 = (LPVOID)GetProcAddress(hDll, "MYDLL_Func1");
            MYDLL_Func2 = (LPVOID)GetProcAddress(hDll, "MYDLL_Func2");

            if (!MYDLL_Func1||
                !MYDLL_Func2)
            {
                FreeLibrary(hDll); hDll= NULL;
            } else {
                Log("were good to go");
            }
        }
    }
    return (hDll!= NULL);
}

now I want to write a wrapper function that will call this function pointer, but in doing so I get an "AccessViolationException"

public ref struct Wrapper sealed abstract
{
    void ManagedFunc(IntPtr hwnd)
    {
        if (BeginDll())
        {
            MYDLL_Func1(reinterpret_cast<HWND>(hwnd.ToPointer));
            MYDLL_Func2();
        }
    }
}

I am not assuming I can call a function pointer in c++/cli code, I am simply wondering a correct way to do this. If I add the api dll's header file and call the functions implicitly, I run into the problem that if the native helper dll is not in the directory with the managed dll the application bombs after the first call. ("AccessViolationException")

Thank You.

A: 
MYDLL_Func1(reinterpret_cast<HWND>(hwnd.ToPointer));

should be

MYDLL_Func1(hwnd.ToPointer());

Casts are evil. Casting a member function to a data pointer is just wrong.

Ben Voigt
A: 

For some reason the correct answer was posted by Hans Passat but it is not available anymore, if anyone wants to know how this was fixed I'll sum it up:

the static declarations of the function pointers were causing each source file to have its own copy so they become the following in the declaration file

extern void (*MYDLL_Func1)(void*);

and in the source file

void (*MYDLL_Func1)(void*);

he also says to change the calling convention to _stdcall, but this is in a .C file but _cdecl compiles just fine.

I did however end up switching back to including the DLL's header file and calling functions implicitly. For some reason with this solution, I was getting a buffer overrun in my C# client when running outside of the debugger. Seeing as the problem did not exsist while trying to debug it, I reverted to a different solution. I suppose I just need to be careful to not include the DLL with my managed DLL and client.

Tom Fobear