How do I pass the address of a c++ method in win32

2020-02-13 07:18发布

问题:

I have a win32 application using a C# library.

The C# library has a method where the Action<T> delegate is a parameter as shown:

public NetSocket(Action<int, int, string> action)

I have a ref class in the win32 application with a method that matches the Action delegates signature.

How exactly do I pass this method as the Action parameter in the NetSocket method listed above?


Ben your solution seem to work but there was a compile error on matching the System:Sting^ input parameter of the action delegate method in the win32 application to the String input parameter of Action delegate in the C# code. The Action delegate in the c# code uses a String as an input parameter and the Action delegate method in the win32 code tries match using a System::String^ to match it but that does not work.

// win 32 app - void ServerClass::ActionMethod(int iCommand, int iClientIndex, System::String^ message)

// win32 app -server = gcnew NetSockets::NetSocket(gcnew Action(this,&ServerClass::ActionMethod));

// csharp - public NetSocket(Action<int, int, string> action)

Is there some marshaling method I need to use to match System::String used in the win32 code to string used in the C# code? Am I passing the System::String wrong or is something else have to be done? What must I do to match the System::String^ message parameter to the string parameter?
Thanks


Been correction I tried your solution and it gave the following error:

1 error C3352: 'void ServerClass::ActionMethod(int,int,System::String ^)' : the specified function does not match the delegate type 'void (void)'


@Ben : Getting close. Now when I compile the code using you solution i get an internal compile error as shown:

error C1001: An internal error has occurred in the compiler.
c:\program files (x86)\microsoft visual studio 9.0\vc\include\msclr\marshal.h 49 1 win32project

The code is compiled in Visual Studio 10 where the Framework 3.5 is used and not 4.0

I checked the line where the internal compile occurs and the error happens here in line 49 in the marshal.h file:

_size = ::WideCharToMultiByte(CP_THREAD_ACP, WC_NO_BEST_FIT_CHARS, _pinned_ptr, _str->Length, NULL, 0, NULL,NULL);
if (_size == 0 && _str->Length != 0)
{
    throw gcnew System::ArgumentException(_EXCEPTION_WC2MB);
}

I guess the error happens because the String::String^ input parameter in the c++ code is not being marshaled probably to the c# code, or the other way around.

I'm not sure what I need to fix the c++ side of the code or the C# side of the code. Any idea?

I guess could just make a c++ dll and have the c# library import the library and call a method in the c++ dll, and then have the win32 application load the c++ dll, but that would seem to be odd to have a library load a w++ dll when the c++ dll used the c# library as a reference.


I checked the line where the internal compile occurs and the error happens here line 49 in the marshal.h file.

_size = ::WideCharToMultiByte(CP_THREAD_ACP, 
                              WC_NO_BEST_FIT_CHARS,
                              _pinned_ptr, 
                              _str->Length, 
                              NULL, .
                              0, 
                              NULL,
                              NULL);
if (_size == 0 && _str->Length != 0)
{
    throw gcnew System::ArgumentException(_EXCEPTION_WC2MB);
}

I guess the error happen because the String::String^ input parameter in the c++ code is not being marshalled probably to the c# code, or the other way around. Not sure id I need to fix the c++ isde of the code or the C# side of the code.

回答1:

If it's a native C++ function, use Marshal.GetDelegateForFunctionPointer

If you're using C++/CLI, which it sounds like (and you should retag the question), you want something along the lines of:

NetSocket(gcnew Action<int,int,String^>(this, &ServerClass::ActionMethod))