Accessing a DLL from C#

  • Thread starter Alfred B. Thordarson
  • Start date
A

Alfred B. Thordarson

I have a problem accessing a DLL using C#.

I'm using C/FRONT with Navision's CFRONT.DLL, which contains the
method:

DBL_S32* DBL_NextKey(DBL_HTABLE hTable, DBL_S32* Key);
typedef signed long int DBL_S32;

In addition the documentation says that "hTable" is the "Handle to the
table" and "Key" is "A table key or a NULL". Trying to access this
method from C# (FYI: I'm using Visual Studio), I see the method
defined as:

object CFRONTClass.NextKey(int hTable,ref object key);

The first parameter is not a problem. I have a valid integer for the
hTable, which works for other methods that don't take "object" as a
parameter. But I would like to send "NULL" (as the documentation
describes) as the second parameter (key), it is this paramter's actual
type that is my problem.

I have spent some time on figuring out what the type should be but I
get type mismatch exceptions for all the different types like int[],
Int32[], object[], etc. In the end I found the IntPtr type and now I'm
writing the code as:

IntPtr[] key=new IntPtr[21];
object keyObject=(object)key;
nav.NextKey(hTableRef,ref keyObject);

This gets me further but doesn't work. Besides, it is not NULL, it is
just a reference to an array of integer pointers (as I understand it).
This code now gives me the following exception:

An unhandled exception of type
'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll
Additional information: Old format or invalid type library.
Unhandled Exception: System.Runtime.InteropServices.COMException
(0x80028019): Old format or invalid type library.
at System.RuntimeType.InvokeDispMethod(String name, BindingFlags
invokeAttr, Object target, Object[] args, Boolean[]
byrefModifiers, Int32 culture, String[] namedParameters)
at System.RuntimeType.InvokeMember(String name, BindingFlags
invokeAttr, Binder binder, Object target, Object[] args,
ParameterModifier[] modifiers, CultureInfo culture, String[]
namedParameters)
at System.RuntimeType.ForwardCallToInvokeMember(String memberName,
BindingFlags flags, Object target, Int32[] aWrapperTypes,
MessageData& msgData)
at CFRONTLib.CFRONTClass.NextKey(Int32 hTable, Object& Key)
at WinNavAccessApp.Form1..ctor() in
c:\alfred\vstudio\wstest\winnavaccessapp\form1.cs:line 90
at WinNavAccessApp.Form1.Main() in
c:\alfred\vstudio\wstest\winnavaccessapp\form1.cs:line 148
The program '[1692] WinNavAccessApp.exe' has exited with code 0 (0x0).

I'm totally stuck here and need some help with changing my code above
so that I send the proper type and value into the NextKey method

I would appreciate all the help you could give me.
 
G

Greg Ewing [MVP]

Alfred, have you tried just passing null like this? I've never used that
dll myself but sounds like that might work for you.

IntPtr[] key=new IntPtr[21];
nav.NextKey(hTableRef, null);

--
Greg Ewing [MVP]
http://www.citidc.com/




Alfred B. Thordarson said:
I have a problem accessing a DLL using C#.

I'm using C/FRONT with Navision's CFRONT.DLL, which contains the
method:

DBL_S32* DBL_NextKey(DBL_HTABLE hTable, DBL_S32* Key);
typedef signed long int DBL_S32;

In addition the documentation says that "hTable" is the "Handle to the
table" and "Key" is "A table key or a NULL". Trying to access this
method from C# (FYI: I'm using Visual Studio), I see the method
defined as:

object CFRONTClass.NextKey(int hTable,ref object key);

The first parameter is not a problem. I have a valid integer for the
hTable, which works for other methods that don't take "object" as a
parameter. But I would like to send "NULL" (as the documentation
describes) as the second parameter (key), it is this paramter's actual
type that is my problem.

I have spent some time on figuring out what the type should be but I
get type mismatch exceptions for all the different types like int[],
Int32[], object[], etc. In the end I found the IntPtr type and now I'm
writing the code as:

IntPtr[] key=new IntPtr[21];
object keyObject=(object)key;
nav.NextKey(hTableRef,ref keyObject);

This gets me further but doesn't work. Besides, it is not NULL, it is
just a reference to an array of integer pointers (as I understand it).
This code now gives me the following exception:

An unhandled exception of type
'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll
Additional information: Old format or invalid type library.
Unhandled Exception: System.Runtime.InteropServices.COMException
(0x80028019): Old format or invalid type library.
at System.RuntimeType.InvokeDispMethod(String name, BindingFlags
invokeAttr, Object target, Object[] args, Boolean[]
byrefModifiers, Int32 culture, String[] namedParameters)
at System.RuntimeType.InvokeMember(String name, BindingFlags
invokeAttr, Binder binder, Object target, Object[] args,
ParameterModifier[] modifiers, CultureInfo culture, String[]
namedParameters)
at System.RuntimeType.ForwardCallToInvokeMember(String memberName,
BindingFlags flags, Object target, Int32[] aWrapperTypes,
MessageData& msgData)
at CFRONTLib.CFRONTClass.NextKey(Int32 hTable, Object& Key)
at WinNavAccessApp.Form1..ctor() in
c:\alfred\vstudio\wstest\winnavaccessapp\form1.cs:line 90
at WinNavAccessApp.Form1.Main() in
c:\alfred\vstudio\wstest\winnavaccessapp\form1.cs:line 148
The program '[1692] WinNavAccessApp.exe' has exited with code 0 (0x0).

I'm totally stuck here and need some help with changing my code above
so that I send the proper type and value into the NextKey method

I would appreciate all the help you could give me.
 
A

Alfred B. Thordarson

No I haven't; because you can't pass a null to a ref parameter. A ref
parameter requires the caller to pass a valid object of the proper
type. My question is what is a proper C# type to a "ref object" that
is being marshalled to the type (signed long int *) in a dll written
in C.
 
A

Alfred B. Thordarson

I also tried to add a reference to the CFRONT.DLL in a managed C++
ClassLibrary Project and then I get the following declaration:

object __gc *NextKey(int, object __gc * __gc *)

If I now use this method as:

Object __gc *key=Navision->NextKey(TableHandle,NULL);

I get An unhandled exception of type 'System.ExecutionEngineException'
occurred in mscorlib.dll. Probably because the DLL doesn't like the
NULL. So, I tried the following code:

Object __gc * __gc *keyPtr;
(*keyPtr)=NULL;
Object __gc *key=Navision->NextKey(TableHandle,keyPtr);

Again I get an exception:

Unhandled Exception: System.NullReferenceException: Object reference
not set to an instance of an object.
at CPPNavLib.Class1.GetKey(Int32 TableHandle, Int32 KeyNo) in
c:\alfred\vstudio\wstest\cppnavlib\cppnavlib.cpp:line 47
at WinNavAccessApp.Form1..ctor() in
c:\alfred\vstudio\wstest\winnavaccessapp\form1.cs:line 91
at WinNavAccessApp.Form1.Main() in
c:\alfred\vstudio\wstest\winnavaccessapp\form1.cs:line 152
The program '[2928] WinNavAccessApp.exe' has exited with code 0 (0x0).

Isn't there someone out there that can help me?
 
G

Greg Ewing [MVP]

Alfred, how about this:

Object o = null;
nav.NextKey(hTableRef, ref o);

--
Greg Ewing [MVP]
http://www.citidc.com/




Alfred B. Thordarson said:
No I haven't; because you can't pass a null to a ref parameter. A ref
parameter requires the caller to pass a valid object of the proper
type. My question is what is a proper C# type to a "ref object" that
is being marshalled to the type (signed long int *) in a dll written
in C.

"Greg Ewing [MVP]" <gewing@_NO_SPAM_citidc.com> wrote in message
Alfred, have you tried just passing null like this? I've never used that
dll myself but sounds like that might work for you.

IntPtr[] key=new IntPtr[21];
nav.NextKey(hTableRef, null);
 
A

Alfred B. Thordarson

Hi Greg.
Object o = null;
nav.NextKey(hTableRef, ref o);

Unfortunatelly you can not send in a ref to null - it compiles but
gives a runtime exception:

An unhandled exception of type 'System.NullReferenceException'
occurred in mscorlib.dll
Additional information: Object reference
not set to an instance of an object.

-Alfred

Greg Ewing said:
Alfred, how about this:

Object o = null;
nav.NextKey(hTableRef, ref o);

--
Greg Ewing [MVP]
http://www.citidc.com/




Alfred B. Thordarson said:
No I haven't; because you can't pass a null to a ref parameter. A ref
parameter requires the caller to pass a valid object of the proper
type. My question is what is a proper C# type to a "ref object" that
is being marshalled to the type (signed long int *) in a dll written
in C.

"Greg Ewing [MVP]" <gewing@_NO_SPAM_citidc.com> wrote in message
Alfred, have you tried just passing null like this? I've never used that
dll myself but sounds like that might work for you.

IntPtr[] key=new IntPtr[21];
nav.NextKey(hTableRef, null);
 
G

Greg Ewing [MVP]

Alfred, you can definitely send a null object as a ref. That error sounds
like the NextKey function isn't checking to make sure the object isn't null
before accessing it. Are you sure you are supposed to pass null as the
second parm?

Here's some code from a simple windows form which demonstrates that this is
possible.

private void Form1_Load(object sender, System.EventArgs e)
{
object o = null;
Test(ref o);
}
private void Test(ref object o)
{
if (o == null)
MessageBox.Show("o was null");
else
MessageBox.Show("o was not null");
}

--
Greg Ewing [MVP]
http://www.citidc.com/

Alfred B. Thordarson said:
Hi Greg.
Object o = null;
nav.NextKey(hTableRef, ref o);

Unfortunatelly you can not send in a ref to null - it compiles but
gives a runtime exception:

An unhandled exception of type 'System.NullReferenceException'
occurred in mscorlib.dll
Additional information: Object reference
not set to an instance of an object.

-Alfred

"Greg Ewing [MVP]" <gewing@_NO_SPAM_citidc.com> wrote in message
Alfred, how about this:

Object o = null;
nav.NextKey(hTableRef, ref o);

--
Greg Ewing [MVP]
http://www.citidc.com/




Alfred B. Thordarson said:
No I haven't; because you can't pass a null to a ref parameter. A ref
parameter requires the caller to pass a valid object of the proper
type. My question is what is a proper C# type to a "ref object" that
is being marshalled to the type (signed long int *) in a dll written
in C.

"Greg Ewing [MVP]" <gewing@_NO_SPAM_citidc.com> wrote in message
Alfred, have you tried just passing null like this? I've never used that
dll myself but sounds like that might work for you.

IntPtr[] key=new IntPtr[21];
nav.NextKey(hTableRef, null);
 

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