Click to See Complete Forum and Search --> : Help Porting C/C++ Function to C#


dvazriel
July 20th, 2009, 06:48 PM
Hi, this is the problem i am having:

I have a PC104 with a ADO card. API's are provided to control ADO card, API is a C Compiled DLL. The example code that shows how to use this API is in C++ and as a initial test i want to port some basic fuctions to C#.

This is whats happening:

C++ Code:



void main(void)
{
char szBuf[512];

if (!OpenBoard6430(BOARD_NO,0x6430,szBuf, &boardconfig))
{
cprintf("\n%s",szBuf);
cprintf("\nIf an other DM6430 application is running,"
" please close it and try again.");
getch();
return;
}
DEVICE_NO = boardconfig.device_no;

//This is the method signature in the H file:
dllExport BOOL OpenBoard6430(int num, int device_id, LPSTR szBuf,
BoardConfig *boardconfig );
//BoardConfig is a simple struct with 2 members.

}


This is the C# code i wrote:



public char[] szBuf = new char[512];
public struct BoardConfig
{
int device_no;
int it_no;
}
BoardConfig board;
[DllImport("drvr6430.dll")]
public static extern bool OpenBoard6430(int num, int id, char[] szBuf, BoardConfig board);

private void button1_Click(object sender, EventArgs e)
{
if (!OpenBoard6430(1, 0x6430, szBuf, board))
{
//
}
else
{
//
}
}


When i click the button, i get a trying to write to protected memory exception.
What am i doing wrong?


Any help will be GREATLY appreciated.

Thanks

BigEd781
July 20th, 2009, 06:51 PM
Are you sure that your types match up, i.e., you are not using an int where the C dll expects a short, something like that? That could cause this, though it may also be the C# struct itself, hard to say. Maybe someone with more pinvoke experience can add more info.

rliq
July 20th, 2009, 07:14 PM
I seem to remember that BOOL is an int type in C++. Unlike C++, C# cannot treat int as bool. I'm looking at the line "if (!OpenBoard6430(...". If that function is returning an int, I'm not quite sure what will happen... If internally C# bool's take up less stack space than C++'s BOOL's, something will get overwritten by the return value.

Incidentally, if "OpenBoard6430" was a C# function returning an int, the application would not compile.

Wild guess, maybe try:

if (!Convert.ToBoolean(OpenBoard6430(...

vcdebugger
July 21st, 2009, 06:55 AM
where have you compiled the C dll ? is it in microsoft visual studio 6.0 ? i.e, versions less than the .NET supported versions...

MadHatter
July 21st, 2009, 11:20 AM
BOOL maps to bool in .net

your config needs to have the "ref" keyword before the type in the method definition and your struct needs to have a structlayout attribute applied to it. remember that C++ int's aren't the same size as C# ints and if you're doing your structure memory layout, if you use the auto layout, your struct will not marshal correctly. you'll have the first 16 bits and the second 16 bits all inside your first int, and the second int will be 0.

dvazriel
July 21st, 2009, 05:53 PM
Thanks for the replies. Someone helped me find the solution:


[DllImport("drvr6430.dll")]
public static extern bool OpenBoard6430(int num, int id, StringBuilder szBuf, out BoardConfig board);


Basically it replaces the char[] with a StringBuilder object and adding the out keyword to boardConfig)

Mad: i am not sure what that struct layout attribute does, can you provide me a quick code example of where that attribute must go? thanks!

vcdebugger
July 21st, 2009, 11:44 PM
Here is the sample piece of code using StructLayout Attribute :


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct ParserMacroInfoTree
{
public ParserMacroInfo Element;
public IntPtr next;
//public IntPtr Right;
}