473,659 Members | 2,886 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Global C Struct

Forgive me for being a C# newbie.

I have read all of the newsgroup posts, MSDN articles, and other websites on
interop and marshalling to send and receive a C struct as a parameter or
return value in a C function call from C#.

My situation is slightly different, because the C struct I have is global.

I have tried different approaches/techniques (string, String, std::string,
IntPtr, Marshal, class, etc.), but none work. I was given a DLL written in
C. It defines a structure and declares a global instance of it, such as:

typedef struct errInfo
{
long number;
char* description;
} ERRINFOSTRUCT;

PUBLIC ERRINFOSTRUCT ERRINFO = { 0, " " };

It also has two global functions:
__declspec(dlle xport) char * GetErrDesc();
__declspec(dlle xport) void SetErr(long, char *);

I need to set the members of ERRINFO directly from C# (not using SetErr),
because :

- I am writing a unit test for GetErrDesc
- The two functions are in two different files ("units")
- We must keep our tests isolated (they cannot depend on other tests or
functions)

In all of my failed attempts to set ERRINFO.descrip tion, all of my calls to
GetErrDesc returned a space (" "). So, it was obvious that my code did not
actually set ERRINFO. As a test, I called SetErr(1, "Test"), and GetErrDesc
then returned a garbled string, so I know SetErr actually set ERRINFO.

I declared GetErrDesc using the [DllImport("C.dl l")] and wish there was a
similar attribute I could use for declaring ERRINFO, but all I could find
was to create my own ERRINFO structure and marshal a copy of it. However, I
do not understand how this concept should even work, since nothing is tying
the managed C# ERRINFO memory to the unmanaged C ERRINFO memory, because there
is no passing of the struct in a function call.

I need to know: 1) how to set the members of C's global ERRINFO from C#; and
2) why I am getting a garbled string returned. My only recourse is to use
C++.NET, and I would rather stick with C#. I am also being forced to use
VS.NET 2002 right now.

Is there someone out there willing to help me with this, please?
(I have spent two 15-hour days on this and am at a stopping point with C#.)
Nov 16 '05 #1
3 2992
Sorry, but what you're looking to do isn't going to happen (from C# anyway).
P/Invoke works only for functions. Data members can't be accessed directly
(you have to provide one or more functions for passing data in or out).

As for the garbled string, you might have to set attribute values on the
P/Invoke definition to specify whether the string is ANSI/ASCII or Unicode.
The marshaller is probably assuming the wrong type of string.

-Rob Teixeira
"Erialc Berts" <er*********@ya hoo.com> wrote in message
news:13******** *************** ***@posting.goo gle.com...
Forgive me for being a C# newbie.

I have read all of the newsgroup posts, MSDN articles, and other websites on interop and marshalling to send and receive a C struct as a parameter or
return value in a C function call from C#.

My situation is slightly different, because the C struct I have is global.

I have tried different approaches/techniques (string, String, std::string,
IntPtr, Marshal, class, etc.), but none work. I was given a DLL written in C. It defines a structure and declares a global instance of it, such as:

typedef struct errInfo
{
long number;
char* description;
} ERRINFOSTRUCT;

PUBLIC ERRINFOSTRUCT ERRINFO = { 0, " " };

It also has two global functions:
__declspec(dlle xport) char * GetErrDesc();
__declspec(dlle xport) void SetErr(long, char *);

I need to set the members of ERRINFO directly from C# (not using SetErr),
because :

- I am writing a unit test for GetErrDesc
- The two functions are in two different files ("units")
- We must keep our tests isolated (they cannot depend on other tests or
functions)

In all of my failed attempts to set ERRINFO.descrip tion, all of my calls to GetErrDesc returned a space (" "). So, it was obvious that my code did not actually set ERRINFO. As a test, I called SetErr(1, "Test"), and GetErrDesc then returned a garbled string, so I know SetErr actually set ERRINFO.

I declared GetErrDesc using the [DllImport("C.dl l")] and wish there was a
similar attribute I could use for declaring ERRINFO, but all I could find
was to create my own ERRINFO structure and marshal a copy of it. However, I do not understand how this concept should even work, since nothing is tying the managed C# ERRINFO memory to the unmanaged C ERRINFO memory, because there is no passing of the struct in a function call.

I need to know: 1) how to set the members of C's global ERRINFO from C#; and 2) why I am getting a garbled string returned. My only recourse is to use
C++.NET, and I would rather stick with C#. I am also being forced to use
VS.NET 2002 right now.

Is there someone out there willing to help me with this, please?
(I have spent two 15-hour days on this and am at a stopping point with

C#.)
Nov 16 '05 #2
Erialc,

This is a little tricky. First, let's address the method declarations.
The GetErrDesc function is a problem, because it returns a pointer to a
character string. Now, it could be doing one of two things. It could be
returning a copy of the string in the description field, or it could be
returning a pointer to the description field itself. My assumption is that
it is doing the former (assuming it is coded correctly).

Now, if this is the case, then you won't be able to do anything without
modifying the original C code. Basically, you would have to write a
function that would return the address of the pointer in memory, like so:

ERRINFOSTRUCT * GetErrInfoPoint er()

You would import this into C# as this:

[DllImport("C.dl l")]
static extern IntPtr GetErrInfoPoint er();

And then you would declare your structure and marshal it back and forth
with a call to the static PtrToStructure method on the Marshal class.

You will NOT want to call GetErrDesc in this case because it will be
allocating memory, and you will have to deallocate it. The thing is, if it
is using new or malloc, you will have to create a wrapper for delete or free
and call that from C# to make sure you dispose of the memory from the string
properly.

Now, if it is not really coded correctly and it returns the pointer in
memory of the description field, then you can just declare the function like
this:

[DllImport("C.dl l")]
static extern IntPtr GetErrDesc();

And call it once, storing the IntPtr in memory. Then, whenever you want
to get the result, just call the static PtrToStringAnsi to get the string.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m
"Erialc Berts" <er*********@ya hoo.com> wrote in message
news:13******** *************** ***@posting.goo gle.com...
Forgive me for being a C# newbie.

I have read all of the newsgroup posts, MSDN articles, and other websites
on
interop and marshalling to send and receive a C struct as a parameter or
return value in a C function call from C#.

My situation is slightly different, because the C struct I have is global.

I have tried different approaches/techniques (string, String, std::string,
IntPtr, Marshal, class, etc.), but none work. I was given a DLL written
in
C. It defines a structure and declares a global instance of it, such as:

typedef struct errInfo
{
long number;
char* description;
} ERRINFOSTRUCT;

PUBLIC ERRINFOSTRUCT ERRINFO = { 0, " " };

It also has two global functions:
__declspec(dlle xport) char * GetErrDesc();
__declspec(dlle xport) void SetErr(long, char *);

I need to set the members of ERRINFO directly from C# (not using SetErr),
because :

- I am writing a unit test for GetErrDesc
- The two functions are in two different files ("units")
- We must keep our tests isolated (they cannot depend on other tests or
functions)

In all of my failed attempts to set ERRINFO.descrip tion, all of my calls
to
GetErrDesc returned a space (" "). So, it was obvious that my code did
not
actually set ERRINFO. As a test, I called SetErr(1, "Test"), and
GetErrDesc
then returned a garbled string, so I know SetErr actually set ERRINFO.

I declared GetErrDesc using the [DllImport("C.dl l")] and wish there was a
similar attribute I could use for declaring ERRINFO, but all I could find
was to create my own ERRINFO structure and marshal a copy of it. However,
I
do not understand how this concept should even work, since nothing is
tying
the managed C# ERRINFO memory to the unmanaged C ERRINFO memory, because
there
is no passing of the struct in a function call.

I need to know: 1) how to set the members of C's global ERRINFO from C#;
and
2) why I am getting a garbled string returned. My only recourse is to use
C++.NET, and I would rather stick with C#. I am also being forced to use
VS.NET 2002 right now.

Is there someone out there willing to help me with this, please?
(I have spent two 15-hour days on this and am at a stopping point with
C#.)

Nov 16 '05 #3
Thank you Rob and Nicholas for replying.
I'm not a happy camper, but that is because of C#'s shortcomings, not
you guys!
Global C structs are pretty common in legacy DLLs whose source code
has fallen by the wayside.
Ah well, back to C++/C++.NET.
Nov 16 '05 #4

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

Similar topics

2
5180
by: Bryan Parkoff | last post by:
….I would like to know which is the best optimization to use global variable or global struct. I always tell C/C++ Compiler to turn on optimization. ….I use underscore between first name and second name for better readable. After optimization, global variables might be misaligned because each global variables must be converted to 32 bits, but I do see that C/C++ Compiler do padding between variables. Struct does the same to do padding....
8
1767
by: Fernan Bolando | last post by:
I have been going through some of the tutorials on the internet regarding coding styles in unix C programming. Most of the stuff I have read do not prefer using global variables, But for multi-file programs it is impossible not to have global variables. I am trying to learn of the best way to check if I am mis-using global variables. How do you guys know if there are to many global variables in your programs? I am not trying to start a...
5
3290
by: PCHOME | last post by:
Hello! I am working on dividing a single C file into several files. Now I encounter a problem about the global variables and can not find a way to solve it. All global variables and codes used to be in that single file, that worked OK. But when I divdie that file into several ones, I have many "invalid use of undefined type" errors. The four files are main.c, main.h, readLP.h, and readLP.c. In readLP.h
13
3069
by: Sunil | last post by:
Hi all, I want to know how good or bad it is using global variables i.e advantages and disadvantages of using global variables. Sunil.
0
8332
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8851
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
8746
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8525
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
6179
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
5649
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();...
1
2750
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
1975
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1737
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.