473,748 Members | 5,232 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

exporting function with parm pointer to struct

I'm exporting (with DllImport) a C-style function with this syntax:

int z9indqry (4_PARM *parm);

4_PARM is a structure declared in a proprietary header file that cannot be
included in my project (due to C# limits).

What would be the other best way to do this? I would like to be able to use
the original struct because these structs have over 40 members each and
there are several more Structs similar to 4_PARM. Also, they are modified by
the company every two months so I'd need to compare and modify my C# structs
everytime they change the h structs.
I'm not going to use wrappers because the dll function calls are working
well when the parms are simple data types (int, char, string, etc...). I
just need a way to be able to call these specialized structs.

Thanks again.

P.S. - I'm pretty sure this is the last question I have regarding unmanaged
code :-))
Nov 15 '05 #1
6 1774
Angel,

If your structures are really that flexible, then I would recommend that
you not use a pointer to the struct, but rather, a pointer to void in the
declaration. This will prevent you from having to recompile, as well as
redefine the C# code (at least for the declaration).

Also, it would imply that you need a better design that is more
flexible, IMO. Changing the structure every two months is very time
consuming. It might make sense to have a keyed collection of some kind to
use.

That being said, with what you have now, you will have to declare the
structure in C#. You will want it to have the same layout in memory as the
structure in C# (remember longs in C are ints in C#, etc, etc). Also, you
will want to adorn the structure with the StructLayout attribute, passing
LayoutKind.Sequ ential to the constructor.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m

"Angel" <none> wrote in message
news:%2******** **********@tk2m sftngp13.phx.gb l...
I'm exporting (with DllImport) a C-style function with this syntax:

int z9indqry (4_PARM *parm);

4_PARM is a structure declared in a proprietary header file that cannot be
included in my project (due to C# limits).

What would be the other best way to do this? I would like to be able to use the original struct because these structs have over 40 members each and
there are several more Structs similar to 4_PARM. Also, they are modified by the company every two months so I'd need to compare and modify my C# structs everytime they change the h structs.
I'm not going to use wrappers because the dll function calls are working
well when the parms are simple data types (int, char, string, etc...). I
just need a way to be able to call these specialized structs.

Thanks again.

P.S. - I'm pretty sure this is the last question I have regarding unmanaged code :-))

Nov 15 '05 #2
Thanks for the post.

I did what you suggested but I still get "This type can not be marshaled as
a structure field" when I call the function. This is my initial code:

[DllImport("C:\\ zm7\\Developm\\ DLL\\ZIP4_W32.D LL")]
public static extern int z9indqry(4_PARM parm);
public static void getParms ()
{
int i;
Zip4_parm parm = new Zip4_parm();
i = z9indqry(parm); // Error: "This type can not be marshaled as a
structure field"
// IntPtr buffer = Marshal.AllocCo TaskMem( Marshal.SizeOf( parm ));
}
What can this error mean?
Also, I'm trying to delare some const vars from the initial H file (eg.
#define Z4_INVADDR 10) but adding it to the cs file that contains the
structs generates error "Expected class, delegate, enum, interface, or
struct".

Any help would be appreciated.

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard .caspershouse.c om> wrote in
message news:#9******** *****@TK2MSFTNG P11.phx.gbl...
Angel,

If your structures are really that flexible, then I would recommend that you not use a pointer to the struct, but rather, a pointer to void in the
declaration. This will prevent you from having to recompile, as well as
redefine the C# code (at least for the declaration).

Also, it would imply that you need a better design that is more
flexible, IMO. Changing the structure every two months is very time
consuming. It might make sense to have a keyed collection of some kind to
use.

That being said, with what you have now, you will have to declare the
structure in C#. You will want it to have the same layout in memory as the structure in C# (remember longs in C are ints in C#, etc, etc). Also, you
will want to adorn the structure with the StructLayout attribute, passing
LayoutKind.Sequ ential to the constructor.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m

"Angel" <none> wrote in message
news:%2******** **********@tk2m sftngp13.phx.gb l...
I'm exporting (with DllImport) a C-style function with this syntax:

int z9indqry (4_PARM *parm);

4_PARM is a structure declared in a proprietary header file that cannot be included in my project (due to C# limits).

What would be the other best way to do this? I would like to be able to use
the original struct because these structs have over 40 members each and
there are several more Structs similar to 4_PARM. Also, they are modified by
the company every two months so I'd need to compare and modify my C#

structs
everytime they change the h structs.
I'm not going to use wrappers because the dll function calls are working
well when the parms are simple data types (int, char, string, etc...).

I just need a way to be able to call these specialized structs.

Thanks again.

P.S. - I'm pretty sure this is the last question I have regarding

unmanaged
code :-))


Nov 15 '05 #3

Hi Angel,

Thank you for posting in the community!

I am confused by your code. In your function declaration:
public static extern int z9indqry(4_PARM parm)
It needs 4_PARM structure, but you construct a Zip4_parm, then pass it to
z9indqry.

What is "Zip4_parm" ?

I think the most recommanded way is do the marshaling and declaration in C#
for your 4_PARM structure. Then use it as:
public static extern int z9indqry(ref 4_PARM parm)

If you still do not want to declare the structure. Just as Nicholas said,
you may use IntPtr, which you need to read and write the structure memory
all by yourself(Which is not recommanded)
Below is the steps:

1). Initialize a byte[] which is the same length as the structure.
2). Initilize the structure byte[] array(Do some write to this byte[] array)
3). Use Marshal.AllocCo TaskMem() to alloc a structure size in unmanaged
memory
4). Use Marshal.Copy(By te[], Int32, IntPtr, Int32) to copy the managed
byte[] array to the unmanaged memory.
5). Use the function like this: public static extern int z9indqry(ref
IntPtr parm)

=============== =============== =============
Please apply my suggestion above and let me know if it helps resolve your
problem.

Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

Nov 15 '05 #4
Thanks for your help. Instead of recreating the C-style struct as a C#
struct, I decided to use it as a class. I think that it's at least
communicating with the dll. This is how my class looks like:

[StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi) ]
public class city
{
public city()
{
}
//[MarshalAs(Unman agedType.LPStr)]
[MarshalAs( UnmanagedType.B yValArray, SizeConst=5 )]
public char detail_code;
public char[] zip_code;
public char[] city_key;
public char zip_class_code;
public char[] city_name;
}

The original:
typedef struct
{
char detail_code;
char zip_code[5+1];
char city_key[6+1];
char zip_class_code;
char city_name[28+1];
} CITY_REC;
When I invoke the function, I receive the error: "Can not marshal field
detail_code of type ZM7.city: Invalid managed/unmanaged type combination
(chars must be paired with U1 or U2)". At least the error specifies a field
(detail_code) inside the class, which I think may be a good sign.

What could it be?

Thanks.

"""Jeffrey Tan[MSFT]""" <v-*****@online.mi crosoft.com> wrote in message
news:oT******** ******@cpmsftng xa06.phx.gbl...

Hi Angel,

Thank you for posting in the community!

I am confused by your code. In your function declaration:
public static extern int z9indqry(4_PARM parm)
It needs 4_PARM structure, but you construct a Zip4_parm, then pass it to
z9indqry.

What is "Zip4_parm" ?

I think the most recommanded way is do the marshaling and declaration in C# for your 4_PARM structure. Then use it as:
public static extern int z9indqry(ref 4_PARM parm)

If you still do not want to declare the structure. Just as Nicholas said,
you may use IntPtr, which you need to read and write the structure memory
all by yourself(Which is not recommanded)
Below is the steps:

1). Initialize a byte[] which is the same length as the structure.
2). Initilize the structure byte[] array(Do some write to this byte[] array) 3). Use Marshal.AllocCo TaskMem() to alloc a structure size in unmanaged
memory
4). Use Marshal.Copy(By te[], Int32, IntPtr, Int32) to copy the managed
byte[] array to the unmanaged memory.
5). Use the function like this: public static extern int z9indqry(ref
IntPtr parm)

=============== =============== =============
Please apply my suggestion above and let me know if it helps resolve your
problem.

Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

Nov 15 '05 #5
Hi, Angel ;)

Try the following

[StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi) ]
public class city
{
public city()
{
}
[MarshalAs(Unman agedType.U1)]
public char detail_code;
[MarshalAs( UnmanagedType.B yValArray, SizeConst=5 )]
public char[] zip_code;
[MarshalAs( UnmanagedType.B yValArray, SizeConst=6 )]
public char[] city_key;
[MarshalAs(Unman agedType.U1)]
public char zip_class_code;
[MarshalAs( UnmanagedType.B yValArray, SizeConst=29 )]
public char[] city_name;
}

You should marshal 'char' as 'UnmanagedType. U1' which means C 'char' and
'char[]' as 'UnmanagedType. ByValArray, SizeConst=size' which means C 'char[size]'.

Also you may need to compile C structure with '#pragma pack push(1)' to remove data alignment.

Angel wrote:
Thanks for your help. Instead of recreating the C-style struct as a C#
struct, I decided to use it as a class. I think that it's at least
communicating with the dll. This is how my class looks like:

[StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Ansi) ]
public class city
{
public city()
{
}
//[MarshalAs(Unman agedType.LPStr)]
[MarshalAs( UnmanagedType.B yValArray, SizeConst=5 )]
public char detail_code;
public char[] zip_code;
public char[] city_key;
public char zip_class_code;
public char[] city_name;
}

The original:
typedef struct
{
char detail_code;
char zip_code[5+1];
char city_key[6+1];
char zip_class_code;
char city_name[28+1];
} CITY_REC;
When I invoke the function, I receive the error: "Can not marshal field
detail_code of type ZM7.city: Invalid managed/unmanaged type combination
(chars must be paired with U1 or U2)". At least the error specifies a field
(detail_code) inside the class, which I think may be a good sign.

What could it be?

Thanks.

"""Jeffrey Tan[MSFT]""" <v-*****@online.mi crosoft.com> wrote in message
news:oT******** ******@cpmsftng xa06.phx.gbl...
Hi Angel,

Thank you for posting in the community!

I am confused by your code. In your function declaration:
public static extern int z9indqry(4_PARM parm)
It needs 4_PARM structure, but you construct a Zip4_parm, then pass it to
z9indqry.

What is "Zip4_parm" ?

I think the most recommanded way is do the marshaling and declaration in


C#
for your 4_PARM structure. Then use it as:
public static extern int z9indqry(ref 4_PARM parm)

If you still do not want to declare the structure. Just as Nicholas said,
you may use IntPtr, which you need to read and write the structure memory
all by yourself(Which is not recommanded)
Below is the steps:

1). Initialize a byte[] which is the same length as the structure.
2). Initilize the structure byte[] array(Do some write to this byte[]


array)
3). Use Marshal.AllocCo TaskMem() to alloc a structure size in unmanaged
memory
4). Use Marshal.Copy(By te[], Int32, IntPtr, Int32) to copy the managed
byte[] array to the unmanaged memory.
5). Use the function like this: public static extern int z9indqry(ref
IntPtr parm)


--
With best regards :)
Dmitry Kostenko
Nov 15 '05 #6

Hi Angel,

Please apply Dmitry's suggestion to see if resolve your problem. Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

Nov 15 '05 #7

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

Similar topics

2
30125
by: M | last post by:
Hello I am trying to build an Oracle PL/SQL Package. Some functions should only be visible from the package, while other functions need to be called from outside. I tried the following: -- begin code snippet ---
26
3130
by: Adam Warner | last post by:
Hello all, I'm very new to C but I have a number of years of Common Lisp programming experience. I'm trying to figure out ways of translating higher order concepts such as closures into C. The code will not be idiomatic C. GCC has an extension to ISO C that permits nested functions: <http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html> For implementing closures they have a serious limitation:
4
2784
by: Angel | last post by:
I'm trying to call a DLL function that receives as parameter a user-defined structure created by the company that made the dll. When I call the function from my main form, I call dllCalls.addVer("string1", "string2") -this is how I created the method in the class. Now, in this static method that uses DllImport to read the dll, I need to move "string1" and "string2" into a structure called PARMS_DIRS since the only way the dll function can...
2
1670
by: Angel | last post by:
I'm exporting a C-style function call with this syntax: int getDate(char *date); I'm trying to export to my c# app like this: public static extern int getDate(System.IntPtr ptr); public void getDate() {
12
2109
by: mohan | last post by:
Hi All, How to implement virtual concept in c. TIA Mohan
4
6952
by: msolem | last post by:
I have some code where there are a set of functions that return pointers to each other. I'm having a bit of a hard time figuring out the correct type to use to do that. The code below works but I'm defining the functions as void*, and then casting when I use them. This code is going into a general purpose framework, and it would be much nicer if the user didn't need to do any casting. Can someone tell me how to set up those typedefs...
3
3653
by: Beta What | last post by:
Hello, I have a question about casting a function pointer. Say I want to make a generic module (say some ADT implementation) that requires a function pointer from the 'actual/other modules' that takes arguments of type (void *) because the ADT must be able to deal with any type of data. In my actual code, I will code the function to take arguments of their real types, then when I pass this pointer through an interface function, I...
9
6535
by: AM | last post by:
Hi, I have a C++ Dll that has a function that is being exported as shown below extern "C" __declspec(dllexport) validationResult __stdcall _validateData(double dataToMat, int time); A structure is defined in the header(.h file) as shown below struct validationResult {
1
570
by: Saad | last post by:
Hi, I have a MC++dll, whose functions i want to use in unmanaged c++. I read that one of the ways to use the managed functions in unmanaged world is by exposing the managed api as flat api. I tried that and with simple data types it worked. But now i need to export a function which needs to take a gc struct as parameter, and then fill some values in it, and then the unmanaged c++ will use that info.
0
9548
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9249
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8244
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6796
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6076
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4607
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4876
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3315
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2787
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.