 |
|
 |
hi all,
i just done a DLL/CLR file using c++. i tested the file on MFC application and its worked well.
but i have problem when test it in a vb windows application.
this is the vb code;
Imports System
Imports System.Runtime.InteropServices
Public Class Form1
Private Declare Auto Function AddNumbers Lib "New_CLR_DLL.DLL" ( _
<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal a As Integer, <MarshalAsAttribute(UnmanagedType.AsAny)> ByVal b As Integer)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim result As Int32
result = AddNumbers(3, 5)
MsgBox(result)
End Sub
End Class
>> the program compiles but when run it, it shows an error (PInvoke restriction: cannot return variants.) near result = AddNumbers (3, 5)
showing marshalDirectiveException was unhandled.
any help will be deeply appreciated..
thanks.
Best Regards,
Gokulakannan.
|
|
|
|
 |
|
 |
Why didn't you use this built-in method?
|
|
|
|
 |
|
 |
TRUE! This one is much simpler! Maybe this API did not exist by the time the author wrote this article?
|
|
|
|
 |
|
 |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Don´t use this code !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Your code works at the first look.
But if you put it into a bigger project you will notice that it fails very ugly.
Your example code only works because you execute the Callback IMMEDIATELY after calling Marshal::StructureToPtr().
But if you let pass some time between calling StructureToPtr() and executing the callback, the application is aborted without any usefull error messasge - a SILENT CRASH.
The reason is that the framework moves objects around in memory and a delegate's address in memory is only valid for a while and then it becomes invalid.
The very strange thing is the way Visual Studio (2003) behaves:
The callbacks functioned in my project when starting the application directly from Visual Studio with the key F5.
But if I started the same application hitting CTRL + F5 it failed!!
THERE IS ABSOLUTELY NO WAY PASSING A MANAGED CALLBACK TO UNMANAGED CODE AS IF IT WAS A REAL C++ CALLBACK.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Don´t use this code !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
There are ONLY few reliable ways to call callbacks from unmanaged C++ code :
1.)
Call a STATIC managed function directly from unmanaged C++ code without using any delegate.
2.)
Create a GCHandle from the delegate and pass the GCHandle to unmanaged code instead of a function pointer.
3.)
If you want something that behaves like a real callback, it becomes more complicated:
Inside your managed class (__gc), which you want to be called back from unmanaged code you have to put an inner unmanaged (__nogc) class.
If you want to see a working code which uses a callback from unmanaged C++ code into a managed class, download the latest version of my CabLib.dll.
There study the file LibExtract.h and you see how to do it the correct way!
You find the latest version of CabLib here
ATTENTION:
You need CabLib version 9.0 from April 2008, in older versions you will not find these callbacks!
----------------------------------
I gave your artivle the worst note because you did a poor testing and I spent an entire weekend finding out the reason and a solution. It seems that you did not understand what Nish wrote in his article.
I asked Codeproject to delete your article as it misleads programmers around the world to waste their time with this code which simply does not work!
Elmü
|
|
|
|
 |
|
 |
This example is very close about my trouble.
I have a function pointer like this :
typedef bool (*name)(void * parameter);
And i have a system call like this :
API(name, param);
When i invoke the API, i dont have error but when i have my function in a class, the compiler
ask me to define parameter ...
thx all of yours reply
|
|
|
|
 |
|
 |
Hi ! This is what I was looking for but, I need to send and received an ArrayList instead just an int. The thing is that when I change the types in the delegate like this:
__delegate void MyDelegate(System::Collections::ArrayList* nArg);
I get eventually this error:
Additional information: Can not marshal parameter #1: The type definition of this type has no layout information.
Should I do differently when using ArrayList instead int??
Thanks
******************
There are 10 types of persons, those who understand binayr numbers, and those who doesn't.
******************
|
|
|
|
 |
|
 |
hi,
any body know how to make managed class as member variable in unmanaged class.
ie
unmaged class
{
managed *p managed;
}
by
baijumax
|
|
|
|
 |
|
 |
Hi,
I tried your approach, but for me only first callback invocation work. Next time the unmanaged machinery is about to invoke the callback, it fails with "NullReferenceException"...
Any idea what could be wrong? Thank you very much!
Ales Pour
|
|
|
|
 |
|
 |
Hi there,
as far as I know, the garbage collector may move managed structs to other location in memory undeterministically. The Pin function should be used to prevent it from doing so.
Also I thougth until a few days ago, that unmanaged structs canot holt references to managed types. This is not true however. Use the gcroot.
It goes like this:
#include
gcroot _object;
This _object needs not to be pinned, because the gcroot pointer is registered with the .net framework. If the object is relocated, the pointer gets updated to the new position.
Ingo
|
|
|
|
 |
|
 |
hi ,
finally i found the solution.
add #include
gcroot m_oManaged;
u have to handle garbage collection explicitly.
by
baijumax
|
|
|
|
 |
|
 |
I had the same problem that only this first callback (into a class-member) worked and later on it failed with "NullReferenceExeption".
Callstack got mixed up with "typedef void (*PFUNC)(int)" but worked with "typedef void (WINAPI *PFUNC)(int)". Well, wrong calling convention
hope it helps
rgds
the unforgiven
|
|
|
|
 |
|
 |
C Callbacks still need to be to static functions. C++ is fine however like you said.
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
 |
|
 |
What happens if I have more than one delegate? Do I have to make a Wrapper Structure for each delagte I have? This would be a little heavy and boring.
Thanx
Ronny
|
|
|
|
 |
|
 |
I find the concept of what you're talking about, very fascinating. However, because I do not run VC++ 7.0, it has little application to me.
If you can come up with a VC++ 6.0 version, I am sure the thousands of other CP members (like myself) who is not running '.NET' would find such a sample, useful.
William
|
|
|
|
 |
|
 |
Thank you for your advise.
For the members who is not running VC 7.0,just get the only one file "createpfnc.cpp" in the source code project.It's ennough.
|
|
|
|
 |
|
 |
VC++ 6.0 does not use "#using <<mscorlib.dll>" as a preprocessor statement. It might be acceptable in VC++ 7.0, but I am getting a fatal error from my VC++ 6.0 compiler for it. (This is in the "createpfnc.cpp" file.)
When I substituted "#include <<mscorlib.dll>" for it, I still get a fatal error because it cannot find the file to open it. Where is the file located?
NOTE: I had to use double angle brackets in front of "mscorlib" in order to get it shown in this message.
Thanks.
William
|
|
|
|
 |
|
 |
erm... given that VC6 doesn't support managed code, this is kind of a dumb request.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
 |
|
 |
I didn't know what 'mscorlib' was back then, and thought the author was giving a substitute I could use.
Who are you acting out anyway? Some kind of CP "justice at large", "gun packing", "setting the record straight" vigilante??? Is that the best kind of constructive thing you can do?
If what was percieved more than 3 years ago doesn't fit in to what have been learnt in the meantime, I'm sure the rest of the CP Community is eternally grateful to you for making current something that occurred way back then.
Don't you have something better to do with your time?
William
Fortes in fide et opere!
|
|
|
|
 |
|
 |
I was actually looked for articles on how to convert a delegate to a function pointer, and I read the comments.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
 |
|
 |
Received an error (from CodeProject) when tried to download source files.
William
|
|
|
|
 |
|
|
 |
|
 |
Yeah. Like a day and five hours later.
William
|
|
|
|
 |