C to C#

V

Vlado Mandic

Hi,

I know this is a pure C# newsgroup, but I might get better luck here then somewhere else...

I need to use a function from a DLL written in C...Actual DLLImports are not a problem, but what is causing me headache is wrapping the structures used by the C DLL in C#.
How to defined and marshal all that mess?

I'm posting below the actual C defines, can anyone point me on how to properly define and marshal them in C#?
struct argtuple { int argdesc; char *arg; };
struct errinfo {
int errnum;
char *errstr;
UINT64 timestamp;
int threadID;
int processID;
int activityID;
char *hostName;
char *programName;
int MsgId;
char *form;
int argcount;
argtuple **arglist; };
struct vallist { struct vallist *next; char value[1]; };
struct attrlist { struct attrlist *next; vallist *values; char name[65]; };
struct resid { char resnum[32]; unsigned long mseq; };
struct resource { attrlist *attrs; resid id; };
struct residlist { struct residlist *next; resid id; };
struct reslist { struct reslist *next; resource res; };
struct resdb_ops {
errinfo *(*create)(struct resdb *resdb, resource *res);
errinfo *(*ro_delete)(struct resdb *resdb, resource *res);
errinfo *(*update)(struct resdb *resdb, resource *res);
errinfo *(*append)(struct resdb *resdb, resource *res);
errinfo *(*retrieve)(struct resdb *resdb, resource *res);
errinfo *(*retlist)(struct resdb *resdb, residlist *rids, attrlist *show, reslist **rlp);
errinfo *(*getids)(struct resdb *resdb, attrlist *query, int nids, residlist **rlp);
errinfo *(*modtime)(struct resdb *resdb, time_t *mtimep);
errinfo *(*rdbclose)(struct resdb *resdb);
errinfo *(*noio)(struct resdb *resdb, int forbidden);
errinfo *(*btrans)(struct resdb *resdb);
errinfo *(*etrans)(struct resdb *resdb);
errinfo *(*vrf_notrans)(struct resdb *resdb); };
struct resdb {
struct resdb *next;
struct resdb_ops *ops;
char * rd_private;
char * rd_public; };
enum rap_direction {
RAP_TOSERVER = 0,
RAP_FROMSERVER = 1,
RAP_FROMMASTER = 2,
rap_direction_Dummy = INT_MIN };
typedef enum rap_direction rap_direction;
 
N

not_a_commie

I think in your case you should write a managed C++ wrapper. Keep the
"argtuple **arglist" all in C++. Declare argtuple in C# as "struct
ArgTuple { int argDesc; string arg; }". Then in managed C++ convert
arg to ASCII using a method described here: http://support.microsoft.com/?kbid=311259.
I don't think the standard .Net string to ASCII conversions are what
you want because you obviously need null terminators on those strings.
 
B

Ben Voigt [C++ MVP]

not_a_commie said:
I think in your case you should write a managed C++ wrapper. Keep the
"argtuple **arglist" all in C++. Declare argtuple in C# as "struct
ArgTuple { int argDesc; string arg; }". Then in managed C++ convert
arg to ASCII using a method described here:
http://support.microsoft.com/?kbid=311259. I don't think the standard
.Net string to ASCII conversions are what
you want because you obviously need null terminators on those strings.

But be careful not to use the outdated buggy Managed Extensions for C++
(which is about 2/3 of that explanation, the last 1/3 is the new C++/CLI
syntax).
 
V

Vlado Mandic

I've done that - small managed DLL in C that wraps functions and structs and
exposes them to C#.
And its fine for parsing results from orginal C DLL, but its still a pain
for passing values from C# to my C DLL to original DLL - just gets too
messy.
I'd like to do it without middle-layer DLL that does nothing but
conversions...

Btw, null-terminated strings are not a problem - they mashal quite nicely in
C# or you can use StringBuilder class natively.
What is a problem for me are two things -
a) c-style linked lists:
struct vallist { struct vallist *next; char value[1]; };
how do i write that in a C# that it exposes enumerator properly (for
loop through members)
b) strange typecasts and double pointers:
errinfo *(*retlist)(struct resdb *resdb, residlist *rids, attrlist
*show, reslist **rlp);
what is this even supposed to be in C#?
 
B

Ben Voigt [C++ MVP]

Vlado said:
I've done that - small managed DLL in C that wraps functions and
structs and exposes them to C#.
And its fine for parsing results from orginal C DLL, but its still a
pain for passing values from C# to my C DLL to original DLL - just
gets too messy.
I'd like to do it without middle-layer DLL that does nothing but
conversions...


Since C# doesn't support these natively (pointers can't be structure
members, can't have pointers into unmanaged memory, etc) you will have to
write the conversion code. This is much much easier in C++/CLI than C#. Is
your problem the conversion code, or the fact that it's in a second DLL?
Multiple netmodules can be linked into a single DLL.
Btw, null-terminated strings are not a problem - they mashal quite
nicely in C# or you can use StringBuilder class natively.
What is a problem for me are two things -
a) c-style linked lists:
struct vallist { struct vallist *next; char value[1]; };
how do i write that in a C# that it exposes enumerator properly
(for loop through members)
b) strange typecasts and double pointers:
errinfo *(*retlist)(struct resdb *resdb, residlist *rids, attrlist
*show, reslist **rlp);
what is this even supposed to be in C#?

not_a_commie said:
I think in your case you should write a managed C++ wrapper. Keep the
"argtuple **arglist" all in C++. Declare argtuple in C# as "struct
ArgTuple { int argDesc; string arg; }". Then in managed C++ convert
arg to ASCII using a method described here:
http://support.microsoft.com/?kbid=311259.
I don't think the standard .Net string to ASCII conversions are what
you want because you obviously need null terminators on those
strings.
 
V

Vlado Mandic

Thanks...i guess i'll have to take that route...
I wrote a piece of conversion code, its going slowly as hell...Still, i
don't see any showstoppers, just my general lack of practise in doing this
type of tasks...
And converting string back and forth (original DLL works as with UTF8, but
exposes ANSI) is making it even worse...

Ben Voigt said:
Vlado said:
I've done that - small managed DLL in C that wraps functions and
structs and exposes them to C#.
And its fine for parsing results from orginal C DLL, but its still a
pain for passing values from C# to my C DLL to original DLL - just
gets too messy.
I'd like to do it without middle-layer DLL that does nothing but
conversions...


Since C# doesn't support these natively (pointers can't be structure
members, can't have pointers into unmanaged memory, etc) you will have to
write the conversion code. This is much much easier in C++/CLI than C#.
Is your problem the conversion code, or the fact that it's in a second
DLL? Multiple netmodules can be linked into a single DLL.
Btw, null-terminated strings are not a problem - they mashal quite
nicely in C# or you can use StringBuilder class natively.
What is a problem for me are two things -
a) c-style linked lists:
struct vallist { struct vallist *next; char value[1]; };
how do i write that in a C# that it exposes enumerator properly
(for loop through members)
b) strange typecasts and double pointers:
errinfo *(*retlist)(struct resdb *resdb, residlist *rids, attrlist
*show, reslist **rlp);
what is this even supposed to be in C#?

not_a_commie said:
I think in your case you should write a managed C++ wrapper. Keep the
"argtuple **arglist" all in C++. Declare argtuple in C# as "struct
ArgTuple { int argDesc; string arg; }". Then in managed C++ convert
arg to ASCII using a method described here:
http://support.microsoft.com/?kbid=311259.
I don't think the standard .Net string to ASCII conversions are what
you want because you obviously need null terminators on those
strings.
 
B

Ben Voigt [C++ MVP]

The code is tedious to write, or it runs slow?

Vlado said:
Thanks...i guess i'll have to take that route...
I wrote a piece of conversion code, its going slowly as hell...Still,
i don't see any showstoppers, just my general lack of practise in
doing this type of tasks...
And converting string back and forth (original DLL works as with
UTF8, but exposes ANSI) is making it even worse...

Ben Voigt said:
Vlado said:
I've done that - small managed DLL in C that wraps functions and
structs and exposes them to C#.
And its fine for parsing results from orginal C DLL, but its still a
pain for passing values from C# to my C DLL to original DLL - just
gets too messy.
I'd like to do it without middle-layer DLL that does nothing but
conversions...


Since C# doesn't support these natively (pointers can't be structure
members, can't have pointers into unmanaged memory, etc) you will
have to write the conversion code. This is much much easier in
C++/CLI than C#. Is your problem the conversion code, or the fact
that it's in a second DLL? Multiple netmodules can be linked into a
single DLL.
Btw, null-terminated strings are not a problem - they mashal quite
nicely in C# or you can use StringBuilder class natively.
What is a problem for me are two things -
a) c-style linked lists:
struct vallist { struct vallist *next; char value[1]; };
how do i write that in a C# that it exposes enumerator properly
(for loop through members)
b) strange typecasts and double pointers:
errinfo *(*retlist)(struct resdb *resdb, residlist *rids,
attrlist *show, reslist **rlp);
what is this even supposed to be in C#?

I think in your case you should write a managed C++ wrapper. Keep
the "argtuple **arglist" all in C++. Declare argtuple in C# as
"struct ArgTuple { int argDesc; string arg; }". Then in managed
C++ convert arg to ASCII using a method described here:
http://support.microsoft.com/?kbid=311259.
I don't think the standard .Net string to ASCII conversions are
what you want because you obviously need null terminators on those
strings.
 
V

Vlado Mandic

Tedious to write, nothing wrong with performance...

So far only 50+ crashes ;) - the problem is i don't really know exactly
how/when original dlls do the allocs/deallocs, so sometimes i have to do
Marshal.AllocCoTaskMem() from managed side and then pass a pointer and
sometimes i get a ready pointer and i have to deallocate it to avoid memory
leaks.

Ben Voigt said:
The code is tedious to write, or it runs slow?

Vlado said:
Thanks...i guess i'll have to take that route...
I wrote a piece of conversion code, its going slowly as hell...Still,
i don't see any showstoppers, just my general lack of practise in
doing this type of tasks...
And converting string back and forth (original DLL works as with
UTF8, but exposes ANSI) is making it even worse...

Ben Voigt said:
Vlado Mandic wrote:
I've done that - small managed DLL in C that wraps functions and
structs and exposes them to C#.
And its fine for parsing results from orginal C DLL, but its still a
pain for passing values from C# to my C DLL to original DLL - just
gets too messy.
I'd like to do it without middle-layer DLL that does nothing but
conversions...


Since C# doesn't support these natively (pointers can't be structure
members, can't have pointers into unmanaged memory, etc) you will
have to write the conversion code. This is much much easier in
C++/CLI than C#. Is your problem the conversion code, or the fact
that it's in a second DLL? Multiple netmodules can be linked into a
single DLL.
Btw, null-terminated strings are not a problem - they mashal quite
nicely in C# or you can use StringBuilder class natively.
What is a problem for me are two things -
a) c-style linked lists:
struct vallist { struct vallist *next; char value[1]; };
how do i write that in a C# that it exposes enumerator properly
(for loop through members)
b) strange typecasts and double pointers:
errinfo *(*retlist)(struct resdb *resdb, residlist *rids,
attrlist *show, reslist **rlp);
what is this even supposed to be in C#?

I think in your case you should write a managed C++ wrapper. Keep
the "argtuple **arglist" all in C++. Declare argtuple in C# as
"struct ArgTuple { int argDesc; string arg; }". Then in managed
C++ convert arg to ASCII using a method described here:
http://support.microsoft.com/?kbid=311259.
I don't think the standard .Net string to ASCII conversions are
what you want because you obviously need null terminators on those
strings.
 
G

gregarican

Tedious to write, nothing wrong with performance...

So far only 50+ crashes ;) - the problem is i don't really know exactly
how/when original dlls do the allocs/deallocs, so sometimes i have to do
Marshal.AllocCoTaskMem() from managed side and then pass a pointer and
sometimes i get a ready pointer and i have to deallocate it to avoid memory
leaks.



The code is tedious to write, or it runs slow?
Vlado said:
Thanks...i guess i'll have to take that route...
I wrote a piece of conversion code, its going slowly as hell...Still,
i don't see any showstoppers, just my general lack of practise in
doing this type of tasks...
And converting string back and forth (original DLL works as with
UTF8, but exposes ANSI) is making it even worse...
Vlado Mandic wrote:
I've done that - small managed DLL in C that wraps functions and
structs and exposes them to C#.
And its fine for parsing results from orginal C DLL, but its still a
pain for passing values from C# to my C DLL to original DLL - just
gets too messy.
I'd like to do it without middle-layer DLL that does nothing but
conversions...
Since C# doesn't support these natively (pointers can't be structure
members, can't have pointers into unmanaged memory, etc) you will
have to write the conversion code.  This is much much easier in
C++/CLI than C#. Is your problem the conversion code, or the fact
that it's in a second DLL? Multiple netmodules can be linked into a
single DLL.
Btw, null-terminated strings are not a problem - they mashal quite
nicely in C# or you can use StringBuilder class natively.
What is a problem for me are two things -
a) c-style linked lists:
   struct vallist { struct vallist *next; char value[1]; };
   how do i write that in a C# that it exposes enumerator properly
(for loop through members)
b) strange typecasts and double pointers:
   errinfo *(*retlist)(struct resdb *resdb, residlist *rids,
attrlist *show, reslist **rlp);
   what is this even supposed to be in C#?
I think in your case you should write a managed C++ wrapper. Keep
the "argtuple **arglist" all in C++. Declare argtuple in C# as
"struct ArgTuple { int argDesc; string arg; }". Then in managed
C++ convert arg to ASCII using a method described here:
http://support.microsoft.com/?kbid=311259.
I don't think the standard .Net string to ASCII conversions are
what you want because you obviously need null terminators on those
strings.- Hide quoted text -

- Show quoted text -

Don't know if this helps, but I had a connect a C# app I was writing
to a C-based DLL file. The whole process was so tedious (and the DLL
had literally a couple hundred methods and properties) that I looked
for a third party app. Found something called the P/Invoke Wizard
(http://www.paulyao.com/resources/tools/pinvoke.asp). This helped me
out a good amount so that I could interface easier...
 
B

Ben Voigt [C++ MVP]

Don't know if this helps, but I had a connect a C# app I was writing
to a C-based DLL file. The whole process was so tedious (and the DLL
had literally a couple hundred methods and properties) that I looked
for a third party app. Found something called the P/Invoke Wizard
(http://www.paulyao.com/resources/tools/pinvoke.asp). This helped me
out a good amount so that I could interface easier...

"methods" and "properties" in C code means COM, in which case .NET generates
all the glue code for you (not always perfectly, I've heard of people having
to customize the primary interop assembly). So I'm not sure what you're
talking about.
 
G

gregarican

"methods" and "properties" in C code means COM, in which case .NET generates
all the glue code for you (not always perfectly, I've heard of people having
to customize the primary interop assembly).  So I'm not sure what you're
talking about.

The DLL file I was needing to hook into wasn't based on COM. I had the
H header file for it and once I ran this P/Invoke Wizard it
automatically generated everything I needed. There were a few odds and
ends that I had to clean-up, but that work was minimal. I was using C#
terminology I suppose, and that's why my meaning was misunderstood. I
had to use the DLL's function calls and there were lots of structs I
had to utilize as a means to this end...
 
V

Vlado Mandic

Thnx for the link - Its a good start...It doesn't do everything perfectly,
but perhaps I can use it as a starting point...

I know the "proper" way is to write a mixed DLL in C that uses native API on
one side and exposes .NET on the other and then use that DLL from C#, but I
just don't like such in between solutions (nothing objectively wrong with
it, its just me)...


gregarican said:
Tedious to write, nothing wrong with performance...

So far only 50+ crashes ;) - the problem is i don't really know exactly
how/when original dlls do the allocs/deallocs, so sometimes i have to do
Marshal.AllocCoTaskMem() from managed side and then pass a pointer and
sometimes i get a ready pointer and i have to deallocate it to avoid
memory
leaks.

message

The code is tedious to write, or it runs slow?
Vlado Mandic wrote:
Thanks...i guess i'll have to take that route...
I wrote a piece of conversion code, its going slowly as hell...Still,
i don't see any showstoppers, just my general lack of practise in
doing this type of tasks...
And converting string back and forth (original DLL works as with
UTF8, but exposes ANSI) is making it even worse...
Vlado Mandic wrote:
I've done that - small managed DLL in C that wraps functions and
structs and exposes them to C#.
And its fine for parsing results from orginal C DLL, but its still a
pain for passing values from C# to my C DLL to original DLL - just
gets too messy.
I'd like to do it without middle-layer DLL that does nothing but
conversions...
Since C# doesn't support these natively (pointers can't be structure
members, can't have pointers into unmanaged memory, etc) you will
have to write the conversion code. This is much much easier in
C++/CLI than C#. Is your problem the conversion code, or the fact
that it's in a second DLL? Multiple netmodules can be linked into a
single DLL.
Btw, null-terminated strings are not a problem - they mashal quite
nicely in C# or you can use StringBuilder class natively.
What is a problem for me are two things -
a) c-style linked lists:
struct vallist { struct vallist *next; char value[1]; };
how do i write that in a C# that it exposes enumerator properly
(for loop through members)
b) strange typecasts and double pointers:
errinfo *(*retlist)(struct resdb *resdb, residlist *rids,
attrlist *show, reslist **rlp);
what is this even supposed to be in C#?
I think in your case you should write a managed C++ wrapper. Keep
the "argtuple **arglist" all in C++. Declare argtuple in C# as
"struct ArgTuple { int argDesc; string arg; }". Then in managed
C++ convert arg to ASCII using a method described here:
http://support.microsoft.com/?kbid=311259.
I don't think the standard .Net string to ASCII conversions are
what you want because you obviously need null terminators on those
strings.- Hide quoted text -

- Show quoted text -

Don't know if this helps, but I had a connect a C# app I was writing
to a C-based DLL file. The whole process was so tedious (and the DLL
had literally a couple hundred methods and properties) that I looked
for a third party app. Found something called the P/Invoke Wizard
(http://www.paulyao.com/resources/tools/pinvoke.asp). This helped me
out a good amount so that I could interface easier...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top