473,382 Members | 1,445 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Would C++/CLI solve PInvoke problems that C# has in this situation? What is the advantages using C++/CLI then C# when PInvoking umanaged C++ Code. Major problems here.

Hey there, this will be somewhat a long post, but any response is
appreciated!

I have done many PInvoke in the past from C++ to C#, but I did PInvoke
within C# not C++/CLI.
Can someone explain more why C++/CLI would be better to PInvoke than doing
the PInvoke in
C#?

Because, usually in C# as you already know we use DLLImport and extern
functions. Last time
when I was PInvoking a robotics library in my Lab, I had issues PInvoking an
"Asynchronous"
method call. Before I go into that, I will explain two methods that I was
PInvoking in the past.

I already finished the .NET Wrapping and already did many helper classes to
make a .NET
framework in that library but I used a small hack which is not comfortable
but all other functions
work great except the one I am having problems.

The two methods that are similar:

deviceScheduleSynchronous = Which polls synchronously ONCE to the device and
executes a call
back to a method that allows me to get any data I want. THIS WORKS

deviceScheduleAsynchronous = Which polls asynchronously ALWAYS IN A LOOP to
the device
and executes the callback within everyloop. This keeps on running since it
spawns a new thread
whenever I execute it. This doesn't work, It crashes, Unexpected crash, with
no valid exception.

Both of the methods have the exact same parameters but different return
types:
long deviceScheduleSynchronous (SchedulerCallback pCallback, void *pData,
unsigned short nPriority)
void deviceScheduleAsynchronous (SchedulerCallback pCallback, void *pData,
unsigned short nPriority)

To make that work, I created my own Thread and loop, and used the
deviceScheduleSynchronous to poll
the device, and it worked flawlessly.

BUT I really want to learn why deviceScheduleAsynchronous didn't work. I am
wondering what
caused the not usefull, not informative exception to occur. Both
deviceScheduleSynchronous, and
deviceScheduleAsynchronous has the same parameter types, but only one of
them worked.

I was going to wrap another device, and it only had a
deviceScheduleAsynchronous method, but an
exception occurs right after the first loop, once again an exception which
doesn't make sense. So I
cannot do the same hack I did before cause there is no single polling.

// C/C++ Interops Thats how it is defined
//
// typedef DeviceCallbackCode (__stdcall *SchedulerCallback)(void
*pData);
// __declspec(dllimport) unsigned long __stdcall
deviceScheduleAsynchronous(SchedulerCallback pCallback, void *pData,
unsigned short nPriority);
//
// C# PInvoke
// public delegate uint SchedulerCallback(object pData);
// [DllImport("robod", EntryPoint = "#22", CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
// public static extern void
deviceScheduleAsynchronous(SchedulerCallback pCallback, IntPtr pData, ushort
nPriority);

Once again, it works for One Method, but doesn't work with the other.
Difference between the too is:
deviceScheduleSynchronous : access Device -GrabData -Done (does this
using the current thread since its synchronous)
deviceScheduleAsynchronous : start infinite loop - GrabData -GoBack
(does this in the thread since it is asynchronous)
So is it my coding problem or is it the manufacturers dll problem? I have
done this with two different manufacturers. It works
great with JAVA using JNI without any problem. Would C++/CLI solve this
issue? Should I go back in the lab and attempt it again?

Thanks!

--
Regards,
Mohamed Mansour
Microsoft Student Partner

--
Regards,
Mohamed Mansour
Microsoft Student Partner

Dec 9 '07 #1
14 3760
>Can someone explain more why C++/CLI would be better to PInvoke than doing
the PInvoke in C#?
I'd say the primary benefit is that you don't have to manually declare
all the functions you want to call, since you likely have declarations
available alreay in a header file. Incorrect declarations is a common
source of errors.

I don't know if it would help with your problem though, there's not
enough information in your post to know what goes wrong and why.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Dec 9 '07 #2
"Mohamed Mansour" <m0@community.nospamwrote in message
news:02**********************************@microsof t.com...
Hey there, this will be somewhat a long post, but any response is
appreciated!

I have done many PInvoke in the past from C++ to C#, but I did PInvoke
within C# not C++/CLI.
Can someone explain more why C++/CLI would be better to PInvoke than doing
the PInvoke in
C#?

Because, usually in C# as you already know we use DLLImport and extern
functions. Last time
when I was PInvoking a robotics library in my Lab, I had issues PInvoking
an "Asynchronous"
method call. Before I go into that, I will explain two methods that I was
PInvoking in the past.

I already finished the .NET Wrapping and already did many helper classes
to make a .NET
framework in that library but I used a small hack which is not comfortable
but all other functions
work great except the one I am having problems.

The two methods that are similar:

deviceScheduleSynchronous = Which polls synchronously ONCE to the device
and executes a call
back to a method that allows me to get any data I want. THIS WORKS

deviceScheduleAsynchronous = Which polls asynchronously ALWAYS IN A LOOP
to the device
and executes the callback within everyloop. This keeps on running since it
spawns a new thread
whenever I execute it. This doesn't work, It crashes, Unexpected crash,
with no valid exception.

Both of the methods have the exact same parameters but different return
types:
long deviceScheduleSynchronous (SchedulerCallback pCallback, void *pData,
unsigned short nPriority)
void deviceScheduleAsynchronous (SchedulerCallback pCallback, void
*pData, unsigned short nPriority)

To make that work, I created my own Thread and loop, and used the
deviceScheduleSynchronous to poll
the device, and it worked flawlessly.

BUT I really want to learn why deviceScheduleAsynchronous didn't work. I
am wondering what
caused the not usefull, not informative exception to occur. Both
deviceScheduleSynchronous, and
deviceScheduleAsynchronous has the same parameter types, but only one of
them worked.

I was going to wrap another device, and it only had a
deviceScheduleAsynchronous method, but an
exception occurs right after the first loop, once again an exception which
doesn't make sense. So I
cannot do the same hack I did before cause there is no single polling.

// C/C++ Interops Thats how it is defined
//
// typedef DeviceCallbackCode (__stdcall *SchedulerCallback)(void
*pData);
// __declspec(dllimport) unsigned long __stdcall
deviceScheduleAsynchronous(SchedulerCallback pCallback, void *pData,
unsigned short nPriority);
//
// C# PInvoke
// public delegate uint SchedulerCallback(object pData);
// [DllImport("robod", EntryPoint = "#22", CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
// public static extern void
deviceScheduleAsynchronous(SchedulerCallback pCallback, IntPtr pData,
ushort nPriority);

Once again, it works for One Method, but doesn't work with the other.
Difference between the too is:
deviceScheduleSynchronous : access Device -GrabData -Done (does this
using the current thread since its synchronous)
deviceScheduleAsynchronous : start infinite loop - GrabData -GoBack
(does this in the thread since it is asynchronous)
So is it my coding problem or is it the manufacturers dll problem? I have
done this with two different manufacturers. It works
great with JAVA using JNI without any problem. Would C++/CLI solve this
issue? Should I go back in the lab and attempt it again?

Thanks!

--
Regards,
Mohamed Mansour
Microsoft Student Partner

--
Regards,
Mohamed Mansour
Microsoft Student Partner

Are you sure you keep a *live* reference for your delegate instance? Note
that the JIT has no idea that a *foreign* thread might call the delegate
target asynchronously and prematurely signal to the GC that the delegate is
free to be collected.

Willy.
Willy.

Dec 9 '07 #3
>
Are you sure you keep a *live* reference for your delegate instance? Note
that the JIT has no idea that a *foreign* thread might call the delegate
target asynchronously and prematurely signal to the GC that the delegate
is free to be collected.

Wiily
Hi,

I don't know what you mean live reference ? I declare the delegate in the
same static class of the Interop Wrapper.
Your reasoning makes sense, but how do I use that reasoning in my code? How
do I make a reference to the delegate if the delegate is public and declared
inside the Interop Class.

public static class MyDevice
{
......

// Here is the delegate ... It is declared here
public delegate uint SchedulerCallback(IntPtr pData);

[DllImport("mydevice", EntryPoint = "#22", CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public static extern uint
deviceScheduleAsynchronous(SchedulerCallback pCallback, IntPtr pData, ushort
nPriority);

.....
}

And I use it like the following ...

main()
{
uint deviceID = MyDevice.Init();
uint schedulerID = MyDevice.deviceAsynchronous(MyDataCallback, (IntPtr)0,
MyDevice.DEFAULT_SCHEDULER_PRIORITY);
MyDevice.Start();
}
private uint MyDataCallback(IntPtr data)
{
float[] pos = new float[2];
MyDevice.GetPosition(pos);
Console.WriteLine("{0} {1}",pos[0],pos[1]);
}
What the above does, it turns on the device and starts it, and it will print
out the data in every iteration of the loop always asynchonously since it is
within a thread. (The C++ API)

So what do you mean live reference? The delegate is created in the same
class as a public delegate of the Interop class. Is that wrong?

Thanks for your help, any more help is appreciated.

--
Regards,
Mohamed Mansour
Microsoft Student Partner

"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:eQ**************@TK2MSFTNGP04.phx.gbl...
"Mohamed Mansour" <m0@community.nospamwrote in message
news:02**********************************@microsof t.com...
>Hey there, this will be somewhat a long post, but any response is
appreciated!

I have done many PInvoke in the past from C++ to C#, but I did PInvoke
within C# not C++/CLI.
Can someone explain more why C++/CLI would be better to PInvoke than
doing the PInvoke in
C#?

Because, usually in C# as you already know we use DLLImport and extern
functions. Last time
when I was PInvoking a robotics library in my Lab, I had issues PInvoking
an "Asynchronous"
method call. Before I go into that, I will explain two methods that I was
PInvoking in the past.

I already finished the .NET Wrapping and already did many helper classes
to make a .NET
framework in that library but I used a small hack which is not
comfortable but all other functions
work great except the one I am having problems.

The two methods that are similar:

deviceScheduleSynchronous = Which polls synchronously ONCE to the device
and executes a call
back to a method that allows me to get any data I want. THIS WORKS

deviceScheduleAsynchronous = Which polls asynchronously ALWAYS IN A LOOP
to the device
and executes the callback within everyloop. This keeps on running since
it spawns a new thread
whenever I execute it. This doesn't work, It crashes, Unexpected crash,
with no valid exception.

Both of the methods have the exact same parameters but different return
types:
long deviceScheduleSynchronous (SchedulerCallback pCallback, void
*pData, unsigned short nPriority)
void deviceScheduleAsynchronous (SchedulerCallback pCallback, void
*pData, unsigned short nPriority)

To make that work, I created my own Thread and loop, and used the
deviceScheduleSynchronous to poll
the device, and it worked flawlessly.

BUT I really want to learn why deviceScheduleAsynchronous didn't work. I
am wondering what
caused the not usefull, not informative exception to occur. Both
deviceScheduleSynchronous, and
deviceScheduleAsynchronous has the same parameter types, but only one of
them worked.

I was going to wrap another device, and it only had a
deviceScheduleAsynchronous method, but an
exception occurs right after the first loop, once again an exception
which doesn't make sense. So I
cannot do the same hack I did before cause there is no single polling.

// C/C++ Interops Thats how it is defined
//
// typedef DeviceCallbackCode (__stdcall *SchedulerCallback)(void
*pData);
// __declspec(dllimport) unsigned long __stdcall
deviceScheduleAsynchronous(SchedulerCallback pCallback, void *pData,
unsigned short nPriority);
//
// C# PInvoke
// public delegate uint SchedulerCallback(object pData);
// [DllImport("robod", EntryPoint = "#22", CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
// public static extern void
deviceScheduleAsynchronous(SchedulerCallback pCallback, IntPtr pData,
ushort nPriority);

Once again, it works for One Method, but doesn't work with the other.
Difference between the too is:
deviceScheduleSynchronous : access Device -GrabData -Done (does this
using the current thread since its synchronous)
deviceScheduleAsynchronous : start infinite loop - GrabData -GoBack
(does this in the thread since it is asynchronous)
So is it my coding problem or is it the manufacturers dll problem? I have
done this with two different manufacturers. It works
great with JAVA using JNI without any problem. Would C++/CLI solve this
issue? Should I go back in the lab and attempt it again?

Thanks!

--
Regards,
Mohamed Mansour
Microsoft Student Partner

--
Regards,
Mohamed Mansour
Microsoft Student Partner

Dec 9 '07 #4
The only reference to the delegate you have is in the call to the unmanaged
function
uint schedulerID = MyDevice.deviceAsynchronous(MyDataCallback, (IntPtr)0,
.....
that means that after the function returns, the delegate instance (root)
becomes eligible for collection, the reason for this is that the JIT, has no
idea how the unmanaged code plans to use the instance, and signals the GC
that the object may get collected .

One way to keep the delegate instance alive [1], is by calling GC.KeepAlive,
passing the delegate reference as argument. You call this method whenever
you are sure you won't get called back by the unmanaged thread code.
[1]
main()
{
uint deviceID = MyDevice.Init();
// Create a delegate instance
SchedulerCallback scb = new SchedulerCallback(MyDataCallback);
// pass the delegate to the unmanaged function
uint schedulerID = MyDevice.deviceAsynchronous(scb, (IntPtr)0,
MyDevice.DEFAULT_SCHEDULER_PRIORITY);
MyDevice.Start();
// Keep the delegate instance alive for as long as you need.
GC.KeepAlive(scb);
}

Willy.
"Mohamed Mansour" <m0@community.nospamwrote in message
news:uC**************@TK2MSFTNGP05.phx.gbl...

Are you sure you keep a *live* reference for your delegate instance? Note
that the JIT has no idea that a *foreign* thread might call the delegate
target asynchronously and prematurely signal to the GC that the delegate
is free to be collected.

Wiily

Hi,

I don't know what you mean live reference ? I declare the delegate in the
same static class of the Interop Wrapper.
Your reasoning makes sense, but how do I use that reasoning in my code?
How do I make a reference to the delegate if the delegate is public and
declared inside the Interop Class.

public static class MyDevice
{
.....

// Here is the delegate ... It is declared here
public delegate uint SchedulerCallback(IntPtr pData);

[DllImport("mydevice", EntryPoint = "#22", CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public static extern uint
deviceScheduleAsynchronous(SchedulerCallback pCallback, IntPtr pData,
ushort nPriority);

....
}

And I use it like the following ...

main()
{
uint deviceID = MyDevice.Init();
uint schedulerID = MyDevice.deviceAsynchronous(MyDataCallback,
(IntPtr)0, MyDevice.DEFAULT_SCHEDULER_PRIORITY);
MyDevice.Start();
}
private uint MyDataCallback(IntPtr data)
{
float[] pos = new float[2];
MyDevice.GetPosition(pos);
Console.WriteLine("{0} {1}",pos[0],pos[1]);
}
What the above does, it turns on the device and starts it, and it will
print out the data in every iteration of the loop always asynchonously
since it is within a thread. (The C++ API)

So what do you mean live reference? The delegate is created in the same
class as a public delegate of the Interop class. Is that wrong?

Thanks for your help, any more help is appreciated.

--
Regards,
Mohamed Mansour
Microsoft Student Partner

"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:eQ**************@TK2MSFTNGP04.phx.gbl...
>"Mohamed Mansour" <m0@community.nospamwrote in message
news:02**********************************@microso ft.com...
>>Hey there, this will be somewhat a long post, but any response is
appreciated!

I have done many PInvoke in the past from C++ to C#, but I did PInvoke
within C# not C++/CLI.
Can someone explain more why C++/CLI would be better to PInvoke than
doing the PInvoke in
C#?

Because, usually in C# as you already know we use DLLImport and extern
functions. Last time
when I was PInvoking a robotics library in my Lab, I had issues
PInvoking an "Asynchronous"
method call. Before I go into that, I will explain two methods that I
was PInvoking in the past.

I already finished the .NET Wrapping and already did many helper classes
to make a .NET
framework in that library but I used a small hack which is not
comfortable but all other functions
work great except the one I am having problems.

The two methods that are similar:

deviceScheduleSynchronous = Which polls synchronously ONCE to the device
and executes a call
back to a method that allows me to get any data I want. THIS WORKS

deviceScheduleAsynchronous = Which polls asynchronously ALWAYS IN A LOOP
to the device
and executes the callback within everyloop. This keeps on running since
it spawns a new thread
whenever I execute it. This doesn't work, It crashes, Unexpected crash,
with no valid exception.

Both of the methods have the exact same parameters but different return
types:
long deviceScheduleSynchronous (SchedulerCallback pCallback, void
*pData, unsigned short nPriority)
void deviceScheduleAsynchronous (SchedulerCallback pCallback, void
*pData, unsigned short nPriority)

To make that work, I created my own Thread and loop, and used the
deviceScheduleSynchronous to poll
the device, and it worked flawlessly.

BUT I really want to learn why deviceScheduleAsynchronous didn't work. I
am wondering what
caused the not usefull, not informative exception to occur. Both
deviceScheduleSynchronous, and
deviceScheduleAsynchronous has the same parameter types, but only one
of them worked.

I was going to wrap another device, and it only had a
deviceScheduleAsynchronous method, but an
exception occurs right after the first loop, once again an exception
which doesn't make sense. So I
cannot do the same hack I did before cause there is no single polling.

// C/C++ Interops Thats how it is defined
//
// typedef DeviceCallbackCode (__stdcall *SchedulerCallback)(void
*pData);
// __declspec(dllimport) unsigned long __stdcall
deviceScheduleAsynchronous(SchedulerCallback pCallback, void *pData,
unsigned short nPriority);
//
// C# PInvoke
// public delegate uint SchedulerCallback(object pData);
// [DllImport("robod", EntryPoint = "#22", CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
// public static extern void
deviceScheduleAsynchronous(SchedulerCallback pCallback, IntPtr pData,
ushort nPriority);

Once again, it works for One Method, but doesn't work with the other.
Difference between the too is:
deviceScheduleSynchronous : access Device -GrabData -Done (does
this using the current thread since its synchronous)
deviceScheduleAsynchronous : start infinite loop - GrabData -GoBack
(does this in the thread since it is asynchronous)
So is it my coding problem or is it the manufacturers dll problem? I
have done this with two different manufacturers. It works
great with JAVA using JNI without any problem. Would C++/CLI solve this
issue? Should I go back in the lab and attempt it again?

Thanks!

--
Regards,
Mohamed Mansour
Microsoft Student Partner

--
Regards,
Mohamed Mansour
Microsoft Student Partner


Dec 9 '07 #5
Hi,

Thanks for your message, but I am still getting the Application to crash if
I am calling the Asynchronous Methods. I said before that When I am calling
unmanaged code asynchronous methods in C# it causes an error, if I call the
exact parameters for the synchronous method, it works fine. Cause there is
an unmanaged thread within the unmanaged method.

I was doing as you mentioned and still getting Application Crash:

// Start scheduler
HD.hdlStart();

SchedulerCallback cb = new
SchedulerCallback(HapticCallback);

uint temp = deviceAsynchronous(cb, (IntPtr)0, 1);

GC.KeepAlive(call);
It crashes right after the first iteration of the calback, so when I trigger
deviceAsynchronous it creates an infinite loop that I can get data from. But
it still seems that It isn't working

Any more ideas what I have done wrong?
--
Regards,
Mohamed Mansour
Microsoft Student Partner

"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:Ok**************@TK2MSFTNGP05.phx.gbl...
The only reference to the delegate you have is in the call to the
unmanaged function
uint schedulerID = MyDevice.deviceAsynchronous(MyDataCallback, (IntPtr)0,
....
that means that after the function returns, the delegate instance (root)
becomes eligible for collection, the reason for this is that the JIT, has
no idea how the unmanaged code plans to use the instance, and signals the
GC that the object may get collected .

One way to keep the delegate instance alive [1], is by calling
GC.KeepAlive, passing the delegate reference as argument. You call this
method whenever you are sure you won't get called back by the unmanaged
thread code.
[1]
main()
{
uint deviceID = MyDevice.Init();
// Create a delegate instance
SchedulerCallback scb = new SchedulerCallback(MyDataCallback);
// pass the delegate to the unmanaged function
uint schedulerID = MyDevice.deviceAsynchronous(scb, (IntPtr)0,
MyDevice.DEFAULT_SCHEDULER_PRIORITY);
MyDevice.Start();
// Keep the delegate instance alive for as long as you need.
GC.KeepAlive(scb);
}

Willy.
"Mohamed Mansour" <m0@community.nospamwrote in message
news:uC**************@TK2MSFTNGP05.phx.gbl...
>
Are you sure you keep a *live* reference for your delegate instance?
Note that the JIT has no idea that a *foreign* thread might call the
delegate target asynchronously and prematurely signal to the GC that the
delegate is free to be collected.

Wiily

Hi,

I don't know what you mean live reference ? I declare the delegate in the
same static class of the Interop Wrapper.
Your reasoning makes sense, but how do I use that reasoning in my code?
How do I make a reference to the delegate if the delegate is public and
declared inside the Interop Class.

public static class MyDevice
{
.....

// Here is the delegate ... It is declared here
public delegate uint SchedulerCallback(IntPtr pData);

[DllImport("mydevice", EntryPoint = "#22", CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public static extern uint
deviceScheduleAsynchronous(SchedulerCallback pCallback, IntPtr pData,
ushort nPriority);

....
}

And I use it like the following ...

main()
{
uint deviceID = MyDevice.Init();
uint schedulerID = MyDevice.deviceAsynchronous(MyDataCallback,
(IntPtr)0, MyDevice.DEFAULT_SCHEDULER_PRIORITY);
MyDevice.Start();
}
private uint MyDataCallback(IntPtr data)
{
float[] pos = new float[2];
MyDevice.GetPosition(pos);
Console.WriteLine("{0} {1}",pos[0],pos[1]);
}
What the above does, it turns on the device and starts it, and it will
print out the data in every iteration of the loop always asynchonously
since it is within a thread. (The C++ API)

So what do you mean live reference? The delegate is created in the same
class as a public delegate of the Interop class. Is that wrong?

Thanks for your help, any more help is appreciated.

--
Regards,
Mohamed Mansour
Microsoft Student Partner

"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:eQ**************@TK2MSFTNGP04.phx.gbl...
>>"Mohamed Mansour" <m0@community.nospamwrote in message
news:02**********************************@micros oft.com...
Hey there, this will be somewhat a long post, but any response is
appreciated!

I have done many PInvoke in the past from C++ to C#, but I did PInvoke
within C# not C++/CLI.
Can someone explain more why C++/CLI would be better to PInvoke than
doing the PInvoke in
C#?

Because, usually in C# as you already know we use DLLImport and extern
functions. Last time
when I was PInvoking a robotics library in my Lab, I had issues
PInvoking an "Asynchronous"
method call. Before I go into that, I will explain two methods that I
was PInvoking in the past.

I already finished the .NET Wrapping and already did many helper
classes to make a .NET
framework in that library but I used a small hack which is not
comfortable but all other functions
work great except the one I am having problems.

The two methods that are similar:

deviceScheduleSynchronous = Which polls synchronously ONCE to the
device and executes a call
back to a method that allows me to get any data I want. THIS WORKS

deviceScheduleAsynchronous = Which polls asynchronously ALWAYS IN A
LOOP to the device
and executes the callback within everyloop. This keeps on running since
it spawns a new thread
whenever I execute it. This doesn't work, It crashes, Unexpected crash,
with no valid exception.

Both of the methods have the exact same parameters but different return
types:
long deviceScheduleSynchronous (SchedulerCallback pCallback, void
*pData, unsigned short nPriority)
void deviceScheduleAsynchronous (SchedulerCallback pCallback, void
*pData, unsigned short nPriority)

To make that work, I created my own Thread and loop, and used the
deviceScheduleSynchronous to poll
the device, and it worked flawlessly.

BUT I really want to learn why deviceScheduleAsynchronous didn't work.
I am wondering what
caused the not usefull, not informative exception to occur. Both
deviceScheduleSynchronous, and
deviceScheduleAsynchronous has the same parameter types, but only one
of them worked.

I was going to wrap another device, and it only had a
deviceScheduleAsynchronous method, but an
exception occurs right after the first loop, once again an exception
which doesn't make sense. So I
cannot do the same hack I did before cause there is no single polling.

// C/C++ Interops Thats how it is defined
//
// typedef DeviceCallbackCode (__stdcall
*SchedulerCallback)(void *pData);
// __declspec(dllimport) unsigned long __stdcall
deviceScheduleAsynchronous(SchedulerCallback pCallback, void *pData,
unsigned short nPriority);
//
// C# PInvoke
// public delegate uint SchedulerCallback(object pData);
// [DllImport("robod", EntryPoint = "#22", CharSet =
CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
// public static extern void
deviceScheduleAsynchronous(SchedulerCallback pCallback, IntPtr pData,
ushort nPriority);

Once again, it works for One Method, but doesn't work with the other.
Difference between the too is:
deviceScheduleSynchronous : access Device -GrabData -Done (does
this using the current thread since its synchronous)
deviceScheduleAsynchronous : start infinite loop - GrabData ->
GoBack (does this in the thread since it is asynchronous)
So is it my coding problem or is it the manufacturers dll problem? I
have done this with two different manufacturers. It works
great with JAVA using JNI without any problem. Would C++/CLI solve this
issue? Should I go back in the lab and attempt it again?

Thanks!

--
Regards,
Mohamed Mansour
Microsoft Student Partner

--
Regards,
Mohamed Mansour
Microsoft Student Partner


Dec 11 '07 #6
Hi Mohamed,

Thanks for your feedback.

With the current information available, it is hard for us to say the root
cause. I also do not believe C++/CLI interop can help to resolve this
problem if the problem lies in the unmanaged side. C++/CLI uses C++ interop
technology to marshal between managed and unmanaged code and it provides
better performance than normal C# p/invoke. Also, it has the advantage of
convenient for interop.

Anyway, I think we have to find out the root cause for your crash first. I
am not sure why the exception you got did not make sense. Can you provide
the detailed stack trace of your crash? For this type of post-mortem
debugging, it is better to use windbg to get the unmanaged/managed mixed
stack trace. Please follow the steps below to obtain a stack trace for
analysis:
"How to debug application crash/hang in production environment?"
http://blogs.msdn.com/msdnts/archive...pplication-cra
sh-hang-in-production-environment.aspx

In addition to the stack trace, you may also provide the exception
information in the debugger output. Also, you may input "!gle" and
".lastevent" commands to understand the last few events before the failure.
Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

Dec 11 '07 #7
Hi Jeffrey,

Since I cannot code this at home, I would have to go back to the University
Lab tomorrow and use their equipment. It is around $10,000 for the hardware.
I am doing this in my spare time to open opportunities for .NET programming
for research (I just graduated this morning from Software Engineering).

I might try another approach other than GC.KeepAlive, maybe I have to pin
the Callback since the memory space gets lost after the first loop.

But Let me rephrase my problem. The application CRASHES after access the
callback once in the Asynchronous Call. The Asynchronous method
"deviceScheduleAsynchronous" in C++ has an infinite loop which poll data
from the device. And That method is an infinite loop which is in its own
thread. All that is in the unmanaged code that the manufacturer provided.
The only thing that is visible to the consumer is :
void deviceScheduleAsynchronous (SchedulerCallback pCallback, void
*pData,unsigned short nPriority)
long deviceScheduleSynchronous (SchedulerCallback pCallback, void *pData,
unsigned short nPriority)

The C# Pinvoke are deviceScheduleAsynchronous(SchedulerCallback pCallback,
IntPtr pData, ushort nPriority); Where SchedulerCallback is a delegate.
Exact same for deviceScheduleSynchronous .

deviceScheduleSynchronous doesn't crash, but deviceScheduleAsynchronous
crashes. It crashes after the first loop.

I will go back to the lab tomorrow and try the following. Maybe I have to
pin the object in the Garbage Collector like the following:

1. deviceScheduleAsynchronous(IntPtr pCallback, IntPtr pData, ushort
nPriority);
2. SchedulerCallback sc = new SchedulerCallback(MyCallBack);
3. IntPtr scPtr = GCHandle.Alloc(sc);
4. deviceScheduleAsynchronous(scPtr, IntPtr.Zero, 0);

I will do a stack trace tomorrow as well.

Thanks!

--
Regards,
Mohamed Mansour
Microsoft Student Partner

""Jeffrey Tan[MSFT]"" <je***@online.microsoft.comwrote in message
news:tT**************@TK2MSFTNGHUB02.phx.gbl...
Hi Mohamed,

Thanks for your feedback.

With the current information available, it is hard for us to say the root
cause. I also do not believe C++/CLI interop can help to resolve this
problem if the problem lies in the unmanaged side. C++/CLI uses C++
interop
technology to marshal between managed and unmanaged code and it provides
better performance than normal C# p/invoke. Also, it has the advantage of
convenient for interop.

Anyway, I think we have to find out the root cause for your crash first. I
am not sure why the exception you got did not make sense. Can you provide
the detailed stack trace of your crash? For this type of post-mortem
debugging, it is better to use windbg to get the unmanaged/managed mixed
stack trace. Please follow the steps below to obtain a stack trace for
analysis:
"How to debug application crash/hang in production environment?"
http://blogs.msdn.com/msdnts/archive...pplication-cra
sh-hang-in-production-environment.aspx

In addition to the stack trace, you may also provide the exception
information in the debugger output. Also, you may input "!gle" and
".lastevent" commands to understand the last few events before the
failure.
Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no
rights.
Dec 11 '07 #8
"Mohamed Mansour" <m0@community.nospamwrote in message
news:E9**********************************@microsof t.com...
Hi,

Thanks for your message, but I am still getting the Application to crash
if I am calling the Asynchronous Methods. I said before that When I am
calling unmanaged code asynchronous methods in C# it causes an error, if I
call the exact parameters for the synchronous method, it works fine. Cause
there is an unmanaged thread within the unmanaged method.

I was doing as you mentioned and still getting Application Crash:

// Start scheduler
HD.hdlStart();

SchedulerCallback cb = new
SchedulerCallback(HapticCallback);

uint temp = deviceAsynchronous(cb, (IntPtr)0, 1);

GC.KeepAlive(call);
It crashes right after the first iteration of the calback, so when I
trigger deviceAsynchronous it creates an infinite loop that I can get data
from. But it still seems that It isn't working

Any more ideas what I have done wrong?
The KeepAlive method should have the delegate reference as argument, not
sure whether "call" is a typo but it should be "cb".

uint temp = deviceAsynchronous(cb, (IntPtr)0, 1);
GC.KeepAlive(call);

should be:

uint temp = deviceAsynchronous(cb, (IntPtr)0, 1);
GC.KeepAlive(cb);

Also you need to keep the delegate alive for as long as you can get called
back from the unmanaged thread. In above snippet, you are only keeping the
delegate alive for the duration of the call into unmanaged, but not any
longer (which makes no sense as this is done automatically by the interop
layer)! That means that when the unmanaged thread calls you back after
KeepAlive(), the call may fail because the delegate might be collected. So
it's up to you put the KeepALive call there where you are sure you won't get
called back any longer.

Willy.

Dec 11 '07 #9

"Mohamed Mansour" <m0@community.nospamwrote in message
news:02**********************************@microsof t.com...
Hey there, this will be somewhat a long post, but any response is
appreciated!

I have done many PInvoke in the past from C++ to C#, but I did PInvoke
within C# not C++/CLI.
Can someone explain more why C++/CLI would be better to PInvoke than doing
the PInvoke in
C#?
Yes, C++/CLI can help in this situation. But don't use p/invoke, it's very
clumsy and no benefit over C#. Use C++ interop instead (codename "It Just
Works").

What you want to do is define a native class with a gcroot member. The
native function can be passed as the callback, and the gcroot will keep the
managed object alive. Then in the native callback, just dereference the
gcroot and call the managed handler function.
Dec 11 '07 #10
Hi Willy,

The "call" was a typo, I did what you have stated

// Start scheduler
HD.hdlStart();

SchedulerCallback cb = new
SchedulerCallback(HapticCallback);

uint temp = deviceAsynchronous(cb, (IntPtr)0, 1);

GC.KeepAlive(cb);

It was crashing after the first iteration, finishes the callback once, and
doesn't repeat it crashes instead. It should repeat

Any ideas why? I am going to the Lab in a bit to try our Pinning the object
as well. And do a stack trace for Jeffery(MSFT).
--
Regards,
Mohamed Mansour
Microsoft Student Partner

"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:Os**************@TK2MSFTNGP02.phx.gbl...
"Mohamed Mansour" <m0@community.nospamwrote in message
news:E9**********************************@microsof t.com...
>Hi,

Thanks for your message, but I am still getting the Application to crash
if I am calling the Asynchronous Methods. I said before that When I am
calling unmanaged code asynchronous methods in C# it causes an error, if
I call the exact parameters for the synchronous method, it works fine.
Cause there is an unmanaged thread within the unmanaged method.

I was doing as you mentioned and still getting Application Crash:

// Start scheduler
HD.hdlStart();

SchedulerCallback cb = new
SchedulerCallback(HapticCallback);

uint temp = deviceAsynchronous(cb, (IntPtr)0, 1);

GC.KeepAlive(call);
It crashes right after the first iteration of the calback, so when I
trigger deviceAsynchronous it creates an infinite loop that I can get
data from. But it still seems that It isn't working

Any more ideas what I have done wrong?

The KeepAlive method should have the delegate reference as argument, not
sure whether "call" is a typo but it should be "cb".

uint temp = deviceAsynchronous(cb, (IntPtr)0, 1);
GC.KeepAlive(call);

should be:

uint temp = deviceAsynchronous(cb, (IntPtr)0, 1);
GC.KeepAlive(cb);

Also you need to keep the delegate alive for as long as you can get called
back from the unmanaged thread. In above snippet, you are only keeping the
delegate alive for the duration of the call into unmanaged, but not any
longer (which makes no sense as this is done automatically by the interop
layer)! That means that when the unmanaged thread calls you back after
KeepAlive(), the call may fail because the delegate might be collected. So
it's up to you put the KeepALive call there where you are sure you won't
get called back any longer.

Willy.
Dec 11 '07 #11
"Mohamed Mansour" <m0@community.nospamwrote in message
news:um**************@TK2MSFTNGP02.phx.gbl...
Hi Willy,

The "call" was a typo, I did what you have stated

// Start scheduler
HD.hdlStart();

SchedulerCallback cb = new
SchedulerCallback(HapticCallback);

uint temp = deviceAsynchronous(cb, (IntPtr)0, 1);

GC.KeepAlive(cb);

It was crashing after the first iteration, finishes the callback once, and
doesn't repeat it crashes instead. It should repeat

Any ideas why? I am going to the Lab in a bit to try our Pinning the
object as well. And do a stack trace for Jeffery(MSFT).
--
Regards,
Mohamed Mansour
Microsoft Student Partner

"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:Os**************@TK2MSFTNGP02.phx.gbl...
>"Mohamed Mansour" <m0@community.nospamwrote in message
news:E9**********************************@microso ft.com...
>>Hi,

Thanks for your message, but I am still getting the Application to crash
if I am calling the Asynchronous Methods. I said before that When I am
calling unmanaged code asynchronous methods in C# it causes an error, if
I call the exact parameters for the synchronous method, it works fine.
Cause there is an unmanaged thread within the unmanaged method.

I was doing as you mentioned and still getting Application Crash:

// Start scheduler
HD.hdlStart();

SchedulerCallback cb = new
SchedulerCallback(HapticCallback);

uint temp = deviceAsynchronous(cb, (IntPtr)0, 1);

GC.KeepAlive(call);
It crashes right after the first iteration of the calback, so when I
trigger deviceAsynchronous it creates an infinite loop that I can get
data from. But it still seems that It isn't working

Any more ideas what I have done wrong?

The KeepAlive method should have the delegate reference as argument, not
sure whether "call" is a typo but it should be "cb".

uint temp = deviceAsynchronous(cb, (IntPtr)0, 1);
GC.KeepAlive(call);

should be:

uint temp = deviceAsynchronous(cb, (IntPtr)0, 1);
GC.KeepAlive(cb);

Also you need to keep the delegate alive for as long as you can get
called back from the unmanaged thread. In above snippet, you are only
keeping the delegate alive for the duration of the call into unmanaged,
but not any longer (which makes no sense as this is done automatically by
the interop layer)! That means that when the unmanaged thread calls you
back after KeepAlive(), the call may fail because the delegate might be
collected. So it's up to you put the KeepALive call there where you are
sure you won't get called back any longer.

Willy.


It makes no sense to put the GC.KeepAlive rigt behind the unmanaged function
call, this won't protect the delegate from being collected, you need to put
the GC.KeepAlive call at the point you are sure the delegate won't get
called back any longer! Be carefull where you declare the delegate, if you
need the delegate to be kept alive for the duration of the program
(AppDomain to be exact) you will have to declare it as static, in that case
you won't need the KeepAlive call as statics have the same lifetime as the
AD they are "part of".

Herewith a small sample illustrating the above, compile both as-is and run
the program, you'll see it works.
Now remove the KeepAlive(or put it right behaind the unmanaged function call
and it will fail.
// C# Test.cs
using System;
using System.Runtime.InteropServices;
using System.Security;

class Program
{
delegate void MyDelegate(int arg);
void MyCallBack(int arg)
{
Console.Write(arg);
}
static void Main()
//
{
Program t = new Program();
MyDelegate del = new MyDelegate(t.MyCallBack);
UnmanagedFunc(del);
GC.Collect();
Console.ReadLine();
GC.KeepAlive(del);
}
[DllImport("MyClib"), SuppressUnmanagedCodeSecurity]
static extern void UnmanagedFunc(MyDelegate f);
}
// C File
// Compile using: cl /LD /O2 MyClib.cpp
#include <windows.h>

typedef void (__stdcall *UnmCallBack)(DWORD b);
DWORD WINAPI ThreadFunc1( PVOID p ) {
for(int i = 0; i < 10; i++)
{
UnmCallBack f = static_cast<UnmCallBack>(p);
f(i);
Sleep(500);
}
return 0;
}

extern "C" void __declspec(dllexport) __stdcall
UnmanagedFunc(PVOID/*LPTHREAD_START_ROUTINE*/ cb)
{
DWORD id = 0;
CreateThread(NULL, 0, ThreadFunc1, (PVOID)cb, 0, &id);
}

Dec 11 '07 #12
Hi Mohamed,

Have you managed to obtain further information regarding the crash? Yes, in
C++/CLI, we normally use GCHandle.Alloc method to pin the callback
delegate, so that it will not cause any crash during unmanaged callback.

Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support

Dec 14 '07 #13
Hi Jeffrey,

I didn't manage to go to the lab yet, there is a huge snow storm in Canada
this week, hopefully tomorrow it will cool down and I can go and do more
testing.

--
Regards,
Mohamed Mansour
Microsoft Student Partner

""Jeffrey Tan[MSFT]"" <je***@online.microsoft.comwrote in message
news:LN**************@TK2MSFTNGHUB02.phx.gbl...
Hi Mohamed,

Have you managed to obtain further information regarding the crash? Yes,
in
C++/CLI, we normally use GCHandle.Alloc method to pin the callback
delegate, so that it will not cause any crash during unmanaged callback.

Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
Dec 16 '07 #14
Hi Mohamed,

Oh, I understand. If you got any progress, please feel free to feedback,
thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support

Dec 17 '07 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
by: Thomas Heller | last post by:
I'm currently working on a new version of py2exe, which will require Python 2.3 and later, because it uses the zipimport mechanism. Since py2exe is a distutils extension, and since C compilers...
39
by: Antoon Pardon | last post by:
I was wondering how people would feel if the cmp function and the __cmp__ method would be a bit more generalised. The problem now is that the cmp protocol has no way to indicate two objects are...
10
by: BBFrost | last post by:
We just recently moved one of our major c# apps from VS Net 2002 to VS Net 2003. At first things were looking ok, now problems are starting to appear. So far ... (1) ...
2
by: Jeff Lederer | last post by:
I have created a simple test C# console program that calls an unmanaged C subroutine in a DLL where one of the arguments is a callback to the C# code. I noticed that when the callback has no...
63
by: Jake Barnes | last post by:
In the course of my research I stumbled upon this article by Alex Russel and Tim Scarfe: http://www.developer-x.com/content/innerhtml/default.html The case is made that innerHTML should never...
4
by: Peter | last post by:
Are there any restrictions in using MarshalAs when p/invoke-ing from a class library as opposed to a windows application in .NET CF 2.0? The following code will not compile in a CF class library...
3
by: Michael | last post by:
Hi all, I believe I'm not PInvoking this struct correctly. Here's the API definition. typedef struct _SP_DRVINFO_DATA { DWORD cbSize; DWORD DriverType; ULONG_PTR Reserved; TCHAR ...
3
by: Michael | last post by:
Hi all, I'm having trouble PInvoking a TCHAR within a struct. I'll paste the specific struct's API definition below. I've tried so many numerous variations. The main Win32 error I get is...
2
by: =?Utf-8?B?VG9ub2ZpdA==?= | last post by:
I've got the following umanaged code that I need to handle in C# code. The data I read comes from an external device, by Read(ID, &data, REGLEN); How should the code look for the structs in ...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.