cornelius1729
New member
- Joined
- Jan 21, 2009
- Messages
- 4
Im trying to write an interface to OpenBUGS (http://mathstat.helsinki.fi/openbugs/) from a C#.NET application. This requires accessing the unmanaged code in the dll BRugs.dll. (Header file here: http://mathstat.helsinki.fi/openbugs/Manuals/Developer/BRugs.html).
I found an example of someone trying to do the same thing, but they used unsafe code, which Id rather avoid. (See http://stackoverflow.com/questions/212155/memory-accessviolationexception-error-calling-dll-from-c)
Ill show you my code so far, and then I have a couple of questions.
Heres the class that deals with the interface:
class BRugs
{
[DllImport(@"c:\Program Files\OpenBUGS\brugs.dll", CharSet = CharSet.Ansi, EntryPoint = "CmdInterpreter")]
public static unsafe extern void CmdInterpreter(ref string command, int* len, int* res); //How do I rewrite this without unsafe?
public static int CmdInterpreterWrapperUnsafe(string command)
{
int success = -1;
unsafe
{
int len = command.ToCharArray().Length;
int* len_ptr = &len;
int res = 0;
int* res_ptr = &res;
BRugs.CmdInterpreter(ref command, len_ptr, res_ptr);
success = *res_ptr;
}
return (success);
}
public static int CmdInterpreterWrapperMarshal(string command)
{
int success = -1;
int len = command.ToCharArray().Length;
IntPtr len_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
Marshal.WriteInt32(len_ptr, len);
int res = 0;
IntPtr res_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
Marshal.WriteInt32(res_ptr, res);
try
{
BRugs.CmdInterpreter(ref command, len_ptr, res_ptr); //What arguments should this take?
success = res; //Is this right?
}
finally
{
Marshal.FreeHGlobal(len_ptr);
Marshal.FreeHGlobal(res_ptr);
}
return (success);
}
}
(Full project code attached.)
The unsafe version seems to run okay, but is presumably subject to the same problems found in the forums post I linked to (and is unsafe).
The Marshalled version does not build; the compiler complains that System.IntPtr cannot be converted to int*.
Sorry about all this preamble, here is my question.
What is the correct way of specifying arguments to CmdInterpreter? It seems that ref string works for char** but is this good practise? And most importantly, what about int*, or double*?
Thanks in advance.
I found an example of someone trying to do the same thing, but they used unsafe code, which Id rather avoid. (See http://stackoverflow.com/questions/212155/memory-accessviolationexception-error-calling-dll-from-c)
Ill show you my code so far, and then I have a couple of questions.
Heres the class that deals with the interface:
class BRugs
{
[DllImport(@"c:\Program Files\OpenBUGS\brugs.dll", CharSet = CharSet.Ansi, EntryPoint = "CmdInterpreter")]
public static unsafe extern void CmdInterpreter(ref string command, int* len, int* res); //How do I rewrite this without unsafe?
public static int CmdInterpreterWrapperUnsafe(string command)
{
int success = -1;
unsafe
{
int len = command.ToCharArray().Length;
int* len_ptr = &len;
int res = 0;
int* res_ptr = &res;
BRugs.CmdInterpreter(ref command, len_ptr, res_ptr);
success = *res_ptr;
}
return (success);
}
public static int CmdInterpreterWrapperMarshal(string command)
{
int success = -1;
int len = command.ToCharArray().Length;
IntPtr len_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
Marshal.WriteInt32(len_ptr, len);
int res = 0;
IntPtr res_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
Marshal.WriteInt32(res_ptr, res);
try
{
BRugs.CmdInterpreter(ref command, len_ptr, res_ptr); //What arguments should this take?
success = res; //Is this right?
}
finally
{
Marshal.FreeHGlobal(len_ptr);
Marshal.FreeHGlobal(res_ptr);
}
return (success);
}
}
(Full project code attached.)
The unsafe version seems to run okay, but is presumably subject to the same problems found in the forums post I linked to (and is unsafe).
The Marshalled version does not build; the compiler complains that System.IntPtr cannot be converted to int*.
Sorry about all this preamble, here is my question.
What is the correct way of specifying arguments to CmdInterpreter? It seems that ref string works for char** but is this good practise? And most importantly, what about int*, or double*?
Thanks in advance.