Using C written DLL function in C# Programm

P

Philipp Tietjen

I have a serious problem, trying to call a C written .dll function in
my c# program! The problem is I only have the already compiled .dll
file and cannot look into the code. I have no problems calling all
functions that are listed in the .dll, that works just fine... except
this one:

The function headers goes like this:
bool AoGetObjAttr(AoObj_t obj_id, AoObjAttr_t *attr);

Importing this function I did that:
[DllImport("DLLNAME", EntryPoint = "AoGetObjAttr"),
System.Security.SuppressUnmanagedCodeSecurity]
private static extern bool AoGetObjAttr(uint obj_id,ref AoObjAttr_t
hAttr);

The AoObjAttr_t is a struct defined as follows:
using AoMask_t=System.UInt32; //Is declared as: typedef unsigned
long AoMask_t; in types.h

[ StructLayout( LayoutKind.Sequential )]
public struct AoObjAttr_t
{
public AoMask_t mask;
public AoHSL_Col_t hsl_col;
public AoRGB_Col_t rgb_col;
public double transparency; //double in types.h
public uint drawstyle; //unsigned int in types.h
public byte visibility; //char in types.h
public byte backfaceulling; //char in types.h
public byte[] obj_name;
//Is declared as:
typedef char AoObjName[251]; in types.h
public byte[] label;
//Is declared as:
typedef char AoObjName[31]; in types.h
public uint obj_type; //unsigned int in types.h
}


To use this function in C# I do the following:
....
AoObjAttr_t hAttr = new AoObjAttr_t();
....

The API documentation says that one should fill the mask paramter with
the following bitwise OR concetenation to get all the values passed to
the hAttr object:
tempMask = 1L << 0|1L << 1|1L << 2|1L << 3|1L << 4|1L << 5|1L << 6|1L
<< 7|1L << 8|1L << 9;

The equivalent in C# would go like this, right?:
hAttr.mask = 1|2|4|8|16|32|64|128|256|512;

hAttr.obj_name = new byte[251];
hAttr.label = new byte[31];

AoGetObjAttr(obj_id,ref hAttr);
....


When I call the function, it writes the correct value to the hsl_col,
rgb_col and visibility variables but leaves both arrays empty! I tried
lots of different types for the arrays and so, but none seems to be
working properly! When I set the "64" value in the mask parameter the
following exception: "Mismatch has occurred between the runtime type of
the array and the sub type recorded in the metadata."
I don't know what to do anymore and I'm thankfull for every bit of help
out there!
 
P

Philipp Tietjen

I think the problem is in the translation between the c++ and the c#
struct! Does anyone has a clue?
 
P

Philipp Tietjen

I changed the following lines in the c# struct definition from:

public byte[] obj_name;
public byte[] label;


to:

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 251)]
public string obj_name;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 31)]
public string label;

The Label Values are now correct! Still no idea why i can't get the
obj_name thing to work.
Any Ideas?
 

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