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

Passing array of sctruct to extern functions?

Hello I am developing a cross-platform solution for scheduled messages,
primary for SMS. The server parts are written in ASNI/ISO C to compile and
run cleanly on any POSIX compatible server.

For the client-side API a generic API in ANSI/ISO C is written as well, and
then wrappers for Perl, Objective-C, C++, COM, Java etc are written on top so
that all developers can use whatever they feel comfortable with (Or more
realistically what their projects already enforces upon them).

So the time has come to .NET, and I have decided to use C#. It is my first
try at C# so some questions I have or decisions I have made might have been
quite alien to you.

Anyway, here is a snippet of a simplefied but representive part of the
ANSI/ISO C header:

ANSI/ISO C
==========

typedef struct NUNuser {
int ID;
char fullname[48];
int manager;
}

typedef struct NUNmessage {
int ID;
int user;
char number[16];
int status;
char number[160];
}

typedef struct NUNmessageheader {
int ID;
int user;
char number[16];
}

NUNstatus NUNgetuserlist(int *userids, uint maxcnt);

NUNstatus NUNgetuser(int userid, NUNuser *user);

NUNstatus NUNgetmessagelist(NUNmessageheader *messageheaders, uint maxcnt);

NUNstatus NUNgetmessage(NUNmessageheader *messageheader, NUNmessage *message);

====

To clear up the examples, NUNstatus is an error code if negative, all
positive number (zero included) are OK.

So to write out all users' names one would do (No error checking done):
void printNames() {
int i;
// If NULL pointer passed for buffer then only count available records
NUNstatus cnt = NUNgetuserlist(NULL, 0);
int *userids = malloc(sizeof(int) * cnt);
// Pass last count AND store new count in case it changed.
cnt = NUNgetuserlist(userids, cnt);
for (i = 0; i < cnt; i++) {
NUNuser user;
NUNgetuser(userids[i], &user);
printf("%d: %s\n", user.ID, user.name);
}
free(userids);
}

As the messages are more complex, with a compound key of ID and the user
that owns the message we can not simply geta list of ints, instead we geta
list of NUNmessageheaders, with the number in it for laughs as it is used
ALLOT and another roundtrip to server is unnecessary.
But here we go:
void printMessages() {
int i;
NUNstatus cnt = NUNgetmessagelist(NULL, 0);
NUNmessageheader *messageheaders = malloc(sizeof(NUNmessageheader) * cnt);
cnt = NUNgetuserlist(messageheaders, cnt);
for (i = 0; i < cnt; i++) {
NUNmessage message;
NUNgetmessage(messageheaders[i], &message);
printf("'%s'\n", message.message);
}
free(messageheaders);
}
Anyway, this is what I have done in C#

C#
==

[StructLayout(LayoutKind.Sequential)]
internal struct NUNuser
{
public int ID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48]
public byte[] fullname;
public int manager;
}

[StructLayout(LayoutKind.Sequential)]
internal struct NUNmessage
{
public int ID;
public int user;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16]
public byte[] number;
public int status;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 160]
public byte[] message;
}

[StructLayout(LayoutKind.Sequential)]
internal struct NUNmessageheader
{
public int ID;
public int user;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16]
public byte[] number;
}

[DllImport("Nuntio.dll")]
public static extern NUNstatus NUNgetuserlist(int[] userids, uint maxcnt);

[DllImport("Nuntio.dll")]
public static extern NUNstatus NUNgetuser(int userid, ref NUNuser user);

[DllImport("Nuntio.dll")]
public static extern NUNstatus NUNgetmessagelist(NUNmessageheader[]
messageheaders, uint maxcnt);

[DllImport("Nuntio.dll")]
public static extern NUNstatus NUNgetmessage(ref NUNmessageheader
messageheader, ref NUNmessage message);

====

That means that the printNames() from the C example works fine. And gets
into something like this:

static void printNames() {
int i;
NUNstatus cnt = NUNgetuserlist(null, 0);
int[] userids = new int[(int)cnt];
cnt = NUNgetuserlist(userids, cnt);
for (i = 0; i < cnt; i++) {
NUNuser user;
NUNgetuser(userids[i], ref user);
Console.WriteLine(user.ID + ": " + user.name);
}
}

This works great, but now to the messages:
void printMessages() {
int i;
NUNstatus cnt = NUNgetmessagelist(null, 0);
NUNmessageheader[] messageheaders = new NUNmessageheader[(int)cnt]; // !!!
cnt = NUNgetuserlist(messageheaders, cnt);
for (i = 0; i < cnt; i++) {
NUNmessage message;
NUNgetmessage(ref messageheaders[i], ref message);
Console.WriteLine(message.message);
}
}

Now at the line marked with "// !!!" nothing happens. No error, it simply
does not fill in the messageheaders array at all.

What am I doing wrong?
Quite allot to read, but unless I define my problem well I can not get a
well defined solution :).

Regards
Fredrik Olsson.
Nov 17 '05 #1
2 1681
Fredrik,
[DllImport("Nuntio.dll")]
public static extern NUNstatus NUNgetmessagelist(NUNmessageheader[]
messageheaders, uint maxcnt); ....Now at the line marked with "// !!!" nothing happens. No error, it simply
does not fill in the messageheaders array at all.

What am I doing wrong?


Try adding the Out attribute to the array parameter

[DllImport("Nuntio.dll")]
public static extern NUNstatus NUNgetmessagelist([Out]
NUNmessageheader[] messageheaders, uint maxcnt);

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 17 '05 #2
"Mattias Sjögren" wrote:
Fredrik,
[DllImport("Nuntio.dll")]
public static extern NUNstatus NUNgetmessagelist(NUNmessageheader[]
messageheaders, uint maxcnt);

....
Now at the line marked with "// !!!" nothing happens. No error, it simply
does not fill in the messageheaders array at all.

What am I doing wrong?


Try adding the Out attribute to the array parameter

[DllImport("Nuntio.dll")]
public static extern NUNstatus NUNgetmessagelist([Out]
NUNmessageheader[] messageheaders, uint maxcnt);


It did the trick, thanks. Guess I should add [Out] to all extern
declarations, even those that work, just for safety? (And performance?)
Nov 17 '05 #3

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

Similar topics

3
by: domeceo | last post by:
can anyone tell me why I cannot pass values in a setTimeout function whenever I use this function it says "menu is undefined" after th alert. function imgOff(menu, num) { if (document.images) {...
58
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
1
by: Sam | last post by:
Hello all I have a two dimensional array (the dimensions are not known) that needs to be passed to fortran from c++, allocate the dimensions of the array in fortran code, do some filling up of...
2
by: Manish | last post by:
Hi, I m facing a problem in re-writing a code from VB to C #. We are using a third party DLL to develop a application of Fax. The current application is already written in VB and we have to...
3
by: Albert Albani | last post by:
Hello I have a problem that I cannot seem to solve I have a c funtion in a DLL that basically looks like func_c (some_struct* s) {...} some_struct is defined like so: struct some_struct {
0
by: nygiantswin2005 | last post by:
I am tring to write simple console application in C# to test the APIs functions made available by the dymo sdk. The dymo sdk provides a dll library that can be used to call functions that will...
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...
40
by: Angus | last post by:
Hello I am writing a library which will write data to a user defined callback function. The function the user of my library will supply is: int (*callbackfunction)(const char*); In my...
1
by: elke | last post by:
Hi, I want to use an unmanaged dll in C# .net and I'm having some troubles witch a function that should return an array. I'm new at this, so I don't know what I'm doing wrong. Here is some...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

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.