I'm trying to build a managed wrapper in C++/CLI for an existing static library written in C.
I have a class where a few callbacks are needed. In the static library you have a function called "set" which registers the callback. However I'm strugling with some managed vs. unmanaged type problems.
Lets say you have a callback with the following prototype:
void f1proc(char *szString, int nSomeOtherData);
Since I want to use String ^ instead of char * in the managed class I think I need to do the following:
1. Create a function with above prototype in my wrapper class.
2. Expose another function (as a delegate) which has similar prototype but use String ^ instead.
3. Have users use the new delegate.
4. When callback is called from the static library it should call my "old" function pointer which is wrapped inside the class which will then do the needed conversion (e.g. use gcnew String(...)) and then call the managed delegate.
Does this make sense If so would anyone be kind to post an example. I'm having some compilation problems because I'm a little unsure how to specify it using the C++/CLI syntax.
One problem is to create a callback function inside a ref class. The function needs to use __stdcall calling convention but the compiler seems to ignore it and tells me I use __cdecl but should use __clrcall instead.

Function pointers and delegates
Pavel Krebs
I am new to .Net so not sure whether I am correct...
I had the same scenario to use my existing static library from .Net applications, and this library needs to send back updates periodically to the application. The static library receives a call back function from the client to notify the application.
The below is what I tried and it works!
I created a c++ .Net class library and created a gc class like below. this internally calls the unmanaged classed in static library, and whenever it needs to notify the client it uses cbPrice which is provided by the client.
namespace PriceClientDotNet
{
public __gc class DataPrice
{
public:
String *subject;
long bid;
long ask;
};
public __delegate void PriceNoti(DataPrice *pPrice);
public __gc class PriceClient
{
public:
void NotifyPriceUpdate(PriceNoti *cbPrice)
{
DataPrice *p = new DataPrice();
p->subject = "test";
cbPrice(p);
}
};
}
and the below is the client application...
private void button1_Click(object sender, System.EventArgs e)
{
PriceClientDotNet.PriceClient cl = new PriceClientDotNet.PriceClient();
PriceClientDotNet.PriceNoti cbP = new PriceClientDotNet.PriceNoti(OnPriceUpdate);
cl.NotifyPriceUpdate(cbP);
}
public void OnPriceUpdate(PriceClientDotNet.DataPrice pPrice)
{
}
may be this can help some one new to .Net !!!
Skvettn
Thanks,
Ayman Shoukry
VC++ Team
Naseem
In case someone is interested you should look into:
http://www.codeproject.com/managedcpp/FuncPtrDelegate.asp
http://msdn2.microsoft.com/en-us/library/3z2x4f55.aspx
What I did was to create 2 callback prototypes. The first one uses native types and is used to interface the C-library. The other one is using pure managed types.
The user of my wrapper then registers a pure managed delegate to the wrapper. The wrapper then registers the delegate with native types to the C library using Marshal::GetFunctionPointerForDelegate() and using GCHandles to make sure it doesn't get relocated.
When a callback occurs I recieve it inside the wrapper using the native type delegate. If a user callback is set, then all the native types are marshalled into managed types and then I explicitly call the user-managed wrapper.
A little bit complicated but with lots of advantages. The outside interface use only managed types, which _should_ make it possible to call from all .NET languages. Testing will tell soon... :-)
-- Henrik Goldman
X-Formation ( http://www.x-formation.com )
havanera
I have on several occasions encountered the need for function pointers while attempting to implement numerical algorithms in VB, and have had to make do with case statements to mathematical functions. As a graduate student I don't find the time to read the newest books on anything related to Microsoft development tools(
MS-press
, wrox, o'reilly) so in effect I am asking if someone can suggest a good book or two at various levels of sophistication above the "step-by-step" level that will assist me in understanding the posting here in order that I can apply it to my own problems. My present understanding is that I can use VB and C++ not C# to realize the desired implementation. I will give a short description of the specific application I am developing in the hopes that any response will be able to make the steps I should take a little clearer.
I would like to pass a function describing a "software reliability growth model" to a root finding algorithm, whether it is model A, model B, or model Z, and have the encapsulated function return the appropriate solution.
Thanks for any assistance that might be provided,
-Lance Fiondella
dba
One thing I forgot to mention was that there is no use of static functions inside the wrapper. This would be a problem if two objects were created of this wrapper and they would start calling each others callbacks.
The only static functions used are in the user class.
Here is an example of how this is done:
m_HeartbeatRetryFeatureDelegate = gcnew HeartbeatRetryFeatureDelegate(this, &My_Wrapper::HeartbeatRetryFeatureDelegateProc);