473,383 Members | 1,762 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,383 software developers and data experts.

Passing structure to unmanaged code from C#

Hi all,

I've been fighting this problem for some time now and am hoping someone can help. I'm converting a VB6 application to C#. Everything I'm about to show works perfect in VB6, but fails in C#.

I'm making an API call into a C dll, passing a structure. The structure gets values modified in the C side and I should see the modified values in my return structure.

Here are the C structures:

Expand|Select|Wrap|Line Numbers
  1. typedef struct
  2. {
  3.     short                vers;                
  4.     short                flags;                
  5.     short                cmd;                
  6.     short                objtype;            
  7.     DWORD                id;                    
  8.     DWORD                client;                
  9.     char                buf[MAX_TOOLBUF];    
  10.     DWORD                toolID;                
  11.     NMSG                msg;                
  12.     DWORD                caller;                
  13.     CLIENTID            clientID;            
  14.     DWORD                ticket;                
  15.         long                spare[4];            
  16. } Request;
  17.  
  18. typedef struct
  19. {
  20.     DWORD        hwnd;
  21.     DWORD        message;
  22.     DWORD        wParam;
  23.     DWORD        lParam;
  24.  
  25. } NMSG;
  26.  
  27.  
In my C# code, I have the following structs defined to map to the C structs above:
Expand|Select|Wrap|Line Numbers
  1.        [StructLayout(LayoutKind.Sequential)]
  2.         public struct NMSG
  3.         {
  4.             [MarshalAs(UnmanagedType.U4)]
  5.             public int hWnd;
  6.             [MarshalAs(UnmanagedType.U4)]
  7.             public int msg;
  8.             [MarshalAs(UnmanagedType.U4)]
  9.             public int wParam;
  10.             [MarshalAs(UnmanagedType.U4)]
  11.             public int lParam;
  12.         }
  13.  
  14.  
  15.         [StructLayout(LayoutKind.Sequential)]
  16.         public struct Request
  17.         {
  18.             [MarshalAs(UnmanagedType.U4)]
  19.             public Int32 vers;        
  20.  
  21.             [MarshalAs(UnmanagedType.U2)]
  22.             public Int16 flags;        
  23.  
  24.             [MarshalAs(UnmanagedType.U2)]
  25.             public Int16 cmd;         
  26.  
  27.             [MarshalAs(UnmanagedType.U4)]
  28.             public int objType;     
  29.  
  30.             [MarshalAs(UnmanagedType.U4)]
  31.             public int id;             
  32.  
  33.             [MarshalAs(UnmanagedType.U4)]
  34.             public int Client;         
  35.  
  36.             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
  37.             public string buf;
  38.  
  39.             [MarshalAs(UnmanagedType.U4)]
  40.             public int toolID;         
  41.  
  42.             [MarshalAs(UnmanagedType.Struct)]
  43.             public NMSG msg;           
  44.  
  45.             [MarshalAs(UnmanagedType.U4)]
  46.             public int caller;        
  47.  
  48.             [MarshalAs(UnmanagedType.U4)]
  49.             public int clientID;       
  50.  
  51.             [MarshalAs(UnmanagedType.U4)]
  52.             public int ticket;         
  53.  
  54.             [MarshalAs(UnmanagedType.U4)]
  55.             public int result;         
  56.  
  57.             [MarshalAs(UnmanagedType.Struct)]
  58.             public MVToolResult res;
  59.  
  60.             [MarshalAs(UnmanagedType.ByValArray, SizeConst= 4) ]
  61.             public int[] spare;       
  62.         }
  63.  
This is the method decoration in the C code:
Expand|Select|Wrap|Line Numbers
  1. SendRequest(Request PTR req)
  2. {
  3. ....
  4. }
  5.  
Here is my PInvoke declaration in C# for the API in C that uses these structures:
Expand|Select|Wrap|Line Numbers
  1.         [DllImport("TheCDLL.dll", EntryPoint = "_Request@4", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  2.         public static extern IntPtr Request(ref Request req);
  3.  
And here is my C# code that fills the structure and makes the API call:
Expand|Select|Wrap|Line Numbers
  1.                 Request req = new Request();
  2.  
  3.                 req.vers = Marshal.SizeOf(req);
  4.  
  5.                 req.vers = 1;
  6.                 req.toolID = 4000;
  7.                 req.Client = 0;
  8.                 req.cmd = 11;
  9.                 req.objType = 1;;
  10.                 req.id = 1;
  11.                 req.msg.hWnd = Hwnd;
  12.                 req.msg.msg = msg;
  13.                 req.msg.wParam = wParam;
  14.                 req.msg.lParam = lParam;
  15.                 req.spare = new int[4];
  16.                 req.buf = new string(' ', 260);
  17.                 req.flags = 11;
  18.  
  19.                 IntPtr retptr = Request(ref req);
  20.  
The problem is, in the VB6 code the structure item 'result' gets filled with a value after I make the API call. In C#, 'result' is always just 0. I'm guessing I must have something wrong with the way I'm marshaling? I've read dozens of articles and have tried lots of different ways to get this working with no success. Any help is appreciated!
Oct 10 '11 #1
2 2458
kadghar
1,295 Expert 1GB
Im not sure, but VB wont let you have empty variables, so it will assign its default value when declared. Wouldn't that be the problem?
Oct 11 '11 #2
Thanks for the suggestion, but all elements in the structure have a default value, so that isn't it.
Oct 11 '11 #3

Sign in to post your reply or Sign up for a free account.

Similar topics

1
by: vijaya | last post by:
I've to invoke a unmanaged dll fucntion in C# which uses a callback fucntion.The unmanaged dll fucntion returns a pointer to a structure to its callback fucntion.The user should collect those...
7
by: Timothy Shih | last post by:
Hi, I am trying to figure out how to use unmanaged code using P/Invoke. I wrote a simple function which takes in 2 buffers (one a byte buffer, one a char buffer) and copies the contents of the byte...
1
by: vijaya | last post by:
I've to invoke a unmanaged dll fucntion in C# which uses a callback fucntion.The unmanaged dll fucntion returns a pointer to a structure to its callback fucntion.The user should collect those...
5
by: adrin | last post by:
hi i have the following problem: i use functions from an external dll(normal w32 unmanaged library) which takes a structure address as an argument.. how do i pass it in c#? i tried using array...
5
by: Philippe Bertrand | last post by:
Using C#, I want to send a byte array to an unmanaged function with the minimum amount of copies. The array is input only and won't be modified (its copied on the unmanaged side). I'm currently...
5
by: GeRmIc | last post by:
Hi, I am doing an interop from unmanaged code to C#. How do i pass an ArrayList pointer from an unmanaged code, (structres are easily passed by between C# and C). //This is the C code ...
2
by: Atmapuri | last post by:
Hi! When records are passed by reference to unmanaged code do they need to be pinned down explicitely or not? I must have gone over this a dozen of times, but I am still not sure about it. I...
5
by: R. MacDonald | last post by:
Hello, all, I am currently working on a .Net (VB) application that invokes routines in unmanaged (Fortran) DLLs. The unmanaged routines then communicate with the .Net application by means of a...
0
by: firstquestion | last post by:
Hello, I need to pass a StringBuilder object to a custom unmanaged DLL. The code most of the time works great, however once in a while I get "Object reference not set to an instance of an object"...
17
by: =?Utf-8?B?U2hhcm9u?= | last post by:
Hi Gurus, I need to transfer a jagged array of byte by reference to unmanaged function, The unmanaged code should changed the values of the array, and when the unmanaged function returns I need...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
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: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
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: 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
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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.