manged callback from unamaged dll

M

MR

help!

I have an unmanaged DLL that I do not have the source code, so i can't
recompile or make changes. the DLL requires a callback function. I would
like to implement the callback method in a managed class. The unmanaged DLL
gets the address of the callback in a struct (someStruct below) that is
passed as a parameter. I can't seem to figure out how to pass the
"unmanaged" address of a managed method to be uses as a callback.

I would appreciate some guidance here

thanks very much

(i am using VS C++ 2005)



// Initialize the callback structure for the Speak&Find object

ref class managedClass

{

SOMESTRUCT someStruct;

someStruct.onResultCallback = &onResult; // HOW DO I ASSIGN THE ADDRESS of
onResult

UnmanagedDLL.Init(&someStruct);

void managedClass::blush:nResult (int, char*, long) // callback for some
unmanaged DLL

{

// some code here

}

}
 
G

Gary Chang[MSFT]

Hi,
... I can't seem to figure out how to pass the "unmanaged"
address of a managed method to be uses as a callback.

yes, you cannot call a .NET function from a unmanaged dll, since there is
no function address for a managed method, it should be a delegate instead,
but you could not pass a delegate to the unmanaged DLL directly, a .NET
type is meaningless to the unmanaged environment.

So in this scenario, I suggest you take the approach which applied in
VS2003, use an unmanaged helper function to call the managed method
instead, then pass this unmanaged function's address to the SOMESTRUCT
struct, please refer to the following CodeProject article for related
sample code:

Calling Managed .NET Function from Unmanaged Windows Custom DLL.
http://www.codeproject.com/csharp/Win32_to_NET.asp


Thanks!

Best regards,

Gary Chang
Microsoft Community Support
--------------------
Get Secure! ¡§C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.asp
&SD=msdn

This posting is provided "AS IS" with no warranties, and confers no rights.
 
P

Paul Howells

Hi,

I think the following code shows how to do this, you might want to pin the
callback before the assignment
to the struct however. Don't be put off by the fact that you don't have
access to the dll code, all you have to do
is construct an equivalant managed struct as I have. I didn't think it was
essential to do it with un-managed
code as suggested by a previous post.

Hope it's not too late.

Paul.

[----------------Start-------------------------]
// This is the main project file for VC++ application project
// generated using an Application Wizard.

#include "stdafx.h"

#using <mscorlib.dll>
#include <tchar.h>

using namespace System;
using namespace System::Runtime::InteropServices;

__delegate bool CallBack(int hwnd, int lParam); // a delegate type

//model this struct exactly like the one passed to your dll function
[StructLayout(LayoutKind::Sequential)]
public __gc struct DllCallBackStruct
{
//this tells the marshaler the delegate is a function ptr
[MarshalAs(UnmanagedType::FunctionPtr)]
CallBack* pcbFunc;
//any other data ...
System::Int32 iData;
};

__gc class EnumReport // managed type with the method to call
{
public:
bool Report(int hwnd, int lParam) { // report the window handle
Console::Write(L"Window handle is ");
Console::WriteLine(hwnd);
return true;
}
};

[DllImport("CallBackModule.dll", EntryPoint = "fnCallEnumWindows", CharSet =
Unicode)]
extern "C" void fnCallEnumWindows(DllCallBackStruct* lpData);

int _tmain(void) {

//create class with callback member
EnumReport* er = new EnumReport;
//create call back object
CallBack* myCallBack = new CallBack(er, &EnumReport::Report);
//create struct that holds callback function
DllCallBackStruct* lpStruct = new DllCallBackStruct();
//assign callback function to struct
lpStruct->pcbFunc = myCallBack;
//call dll
fnCallEnumWindows(lpStruct);

return 0;
}

/////////////////////////////////////////////////Dll Code used to test
idea///////////////////////////////////////////////

struct CALLBACKMODULE_API DllCallBackStruct {
WNDENUMPROC lpcbFunc;
long lData;
};

extern "C" CALLBACKMODULE_API void fnCallEnumWindows(DllCallBackStruct*
lpData);


CALLBACKMODULE_API void fnCallEnumWindows(DllCallBackStruct* lpData)
{
EnumWindows(lpData->lpcbFunc, 99);
}

[----------------Finsih------------------------]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top