|
Hi all,
I've been stuck for the last two days on quite a strange problem. Here's what's happening: I'm calling a C++ function defined in some dll. Some of the parameters in the function are defined as 'out'. The problem that I am facing is with the out parameters, some of the data is 'lost' in transition.
Perhaps some code will help. The following is the C# wrapper function:
[DllImport("SomeDll.dll", EntryPoint = "SomeFunction")]<br />
private static extern bool SomeFunction(<br />
[MarshalAs(UnmanagedType.LPStr)] string str1,<br />
[MarshalAs(UnmanagedType.LPStr)] string str2,<br />
[MarshalAs(UnmanagedType.LPStr)] string str3,<br />
[MarshalAs(UnmanagedType.LPStr)] string str4,<br />
long longNum,<br />
out SomeStruct dataStruct,<br />
out int int1,<br />
out int int2);<br />
And this is the prototype of the C++ function that is being called:
BOOL SomeFunction(<br />
const char* str1,<br />
const char* str2,<br />
const char* str3,<br />
const char* str4,<br />
const long longNum, <br />
SomeStruct* dataStruct,<br />
int& int1,<br />
int& int2)<br />
When I step through the C# code, I find that the dataStruct structure is returned as 'null' (i.e. all values zeroed). The value of int2 is being returned correctly but in the 'position' of int1. The int2 that is returned is unchanged from before the function was invoked. I.e. if I expect to get 5000 from int2, int1 would instead give me that value of 5000 and int2 would be unchanged.
When I step through the C++ code, I find that the dataStruct structure is being received as null from the C# caller but the two ints are set to the correct values before the routine finishes.
The four strings and the long are passed in without any problems.
Based on what I see with the null structure (it should not be observed as being null on the C++ side as it had already been allocated some memory in the C# side of things) and the strange behaviour of int1 and int2, my guess is that the problem lies in how the parameters are being 'wired up'. Unfortunately, I can't see where I've screwed up (the SomeStruct structure is used in other routines in almost exactly the same way and works fine there).
Would appreciate any ideas/comments.
cheers!
|
|
|
|
|
jozsurf wrote: the SomeStruct structure is used in other routines in almost exactly the same way and works fine there
almost is the operative word I guess.
The symptoms you describe correspond to a problem with stack offsets, due to the
fact SomeObject is handled differently by both sides.
Your C function seems to output a pointer to some "SomeStruct". The wrapper function
needs to know how to convert such pointer into a "SomeStruct" itself.
You did not show the definition of SomeStruct; it probably needs some marshaling attributes.
Alternatively you could accept the pointer (have IntPtr in the prototype) and do the
conversion yourself, maybe using Marshal.PtrToStructure
|
|
|
|
|
Thanks for your reply Luc,
I tried using an IntPtr to get the pointer back (don't actually need to use the struct, just want to marshal the parameters correctly as I need the two ints at the end of the parameter list) but wasn't too successful. Unfortunately the values returned were same as before.
Nevertheless, you've given me a bit more food for thought; I've got a couple more things I can explore to get this going. I don't suppose you (or anyone else) could recommend a good learning resource for doing marshalling/interop stuff? I find that I'm wasting a lot of time doing things by trial and error and learning bits and pieces along the way...
cheers!
|
|
|
|
|
Hi,
lots of prototypes can be found on www.pinvoke.net
apart from that I discovered how to do what I needed by trial and error, I have no
definite tutorial or so.
best seems to experiment with own code on both sides (C# and C) so one can experiment
at will, and log everything.
Later on I also discovered there are quite a lot of articles on CodeProject that
use PInvoke...
BTW: you are not having trouble with Win64 are you ? (If you build one side with
64-bit pointers, so must be the other).
|
|
|
|
|
Hi,
I didn't get the e-mail notification for your last post, Luc! I came on to post the solution and just saw it...if I had read it, I possibly could have arrived at the solution much sooner.
Unsure if this was the situation you meant with the 64 bit pointers, but the problem was to do with the difference in definition of C#'s long (a 64 bit int) and C++'s long (a 32 bit int). Equating the two data types to be the same (as I was doing) was pushing the stack out of alignment.
cheers!
|
|
|
|
|
Yes, both Java and C# have real longs, twice the size of an int (as opposed to the
"long is at least as capable as int" in C and C++).
Tho that was not what I was hinting at; some people have difficulty combining
Win32 and Win64 code (having 4B and 8B pointers).
|
|
|
|
|
Hello,
Is there a way to display a custom image within a messageBox? Traditionally you would load custom text, but what about an image?
Thanks in advance!
Mr. O
|
|
|
|
|
I suspect you'd just create your own form and show it instead.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
This[^] article may help.
/ravi
|
|
|
|
|
I think you must create ur own form.give same appearance as message box.make some setting changes. allow user to give image filename in some custom property.
Regards
Chintan
www.visharadsoft.com
(Nothing is so purify as KNOWLEDGE)
|
|
|
|
|
C# codes on how to connect to a Access database stored in C:\my documents\mydatabase.mdb
|
|
|
|
|
|
|
Convert ? No. Create an image and draw the path onto it.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
Hello,
sorry, second post tonight, i feel like i'm flooding this board !
This is probably going to sound really stupid: Is a .dll file just a class?
Is it possible to browse the .dll file and see what Methods is provides?
BACKGROUND :
I just saw how to make my computer Beep via P/Inovke using the following code:
<br />
[DllImport("kernel32.dll")]<br />
public static extern bool Beep(int freq, int duration);<br />
From what i gather, we need to go via this route because the .NET doesn't provide
functionality for sound. What i'm thinking now is that there must be loads of other things
that the .NET can't do and how would i go about finding out what else is out there? (other than having been a programmer since before the .NET )
I tried adding a reference to the kernel32.dll, with the mind that then i might be able to 'view it's contents' using the object-browser but i got an error.
Thanks ..
|
|
|
|
|
Ylno wrote: sorry, second post tonight, i feel like i'm flooding this board !
LOL - that's hardly flooding.
Ylno wrote: From what i gather, we need to go via this route because the .NET doesn't provide
functionality for sound
Not entirely true, I thought .NET 2.0 had some sound functionality, to play wave files at least. And you can play most file formats with the media player control. It *is* true that p/invoke is the way to call APIs that give you things .NET does not.
Ylno wrote: I tried adding a reference to the kernel32.dll, with the mind that then i might be able to 'view it's contents' using the object-browser but i got an error.
You can only do that with .NET dlls. p/invoke is for dlls that are not.
A dll is a bunch of code without an entry point, basically. www.pinvoke.net[^] provides signatures for calling lots of Win32 API methods and probably comes close to giving you a complete list of what's in those dlls, and what they are called.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
Cheers Christian,
That is exactly what i wanted. Thanks !
One thing :
Christian Graus wrote: A dll is a bunch of code without an entry point,
I guess your referring to the Main() method. Does this mean basically that these files have usable code within but not are not in themselves excecutable?
Are the .dlls be written in C ? if so would that mean that their code could be viewed in a C compiler?
|
|
|
|
|
Ylno wrote: Does this mean basically that these files have usable code within but not are not in themselves excecutable?
Some dlls just contain resources. Most contain code, but no way to execute that code, nothing that can run without being called. So, they contain typically libraries that you reference and call from your main program.
Ylno wrote: Are the .dlls be written in C ?
Yes, in this case.
Ylno wrote: if so would that mean that their code could be viewed in a C compiler?
No, C# and VB.NET are different to C, C compiles down to machine code and cannot be decompiled to readable code, at least not in the way that .NET code can.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
Thank you again,
You've cleared somethings up in my mind.
|
|
|
|
|
I tries to open file big than 2^32 bytes. it's not working because it pass the maximum addressing in the memory and it stucks the computer. is there a solution for that problem??????
|
|
|
|
|
There should be no problem opening the file. Are you saying that you are trying to read the entire file into memory?
If so, then the solution is simple: Don't. Just read the part of the file that you are currently working with.
---
single minded; short sighted; long gone;
|
|
|
|
|
>4GB?? You're never going to read the entire file into memory. You have to process it piece by piece.
|
|
|
|
|
As long as you're running NTFS, you should be able to open the file. You can't read it all into memory, of course; that's what FileStream [^]is for: read in small chunks at a time.
|
|
|
|
|
computer cannot run this line if i try to open file bigger than 4GB
fs = File.OpenRead(path)
but the question, how can i open it in pieces?
|
|
|
|
|
I just read an article on parsing in c# and they said that unlike older languages, parsing in c# in simple terms, for a beginner, can be a nightmare.
All I want to do is store room descriptors in a text file with a dillimeter and a value.
- The first value is used to find the correct line to print. e.g 01
- The second part being the name of the room, or unless its the rooms look value, e.g 011
- The third part being the description of your initial impression before looking closer.
Data in the text file...
01,WestHall,The room is filled with old pottery and cobwebs.:
011,Searching the room you notice a hole where a key might fit.:
02,EastHall,Several torches line the walls, and a chest rests upon a stone slab in the back.:
021,Searching the room you notice the flames on the torches are not moving, almost as if...:
Is it possible to pull this data out in chunks using StreamReader?
Unless... I just thought of something as I write this very moment.
Can I say...
ReadToEnd, this entire text file and say drop it in to a string variable.
Then from their use some sort of character searching in the string?
Thanks for your help ahead of time.
|
|
|
|