int32 to native int

P

Paul Brun

Can this be done? Is there a way to "de-alias" the int datatype so I can
pass an int into a C method??

Paul
 
P

Paul Brun

then, why would I get a NullReferenceException when trying to call a C
function:

Unhandled Exception: System.NullReferenceException: Object reference not
set to an instance of an object.
at SXInit(Int32 )

which is defined as:

extern int SXInit(int, ...);

in my C header file. The C header file has many more C functions, and have
problems with them as well, so if
I solve it for one, I will solve it for the others as well.

Thanks
Paul
 
D

Doug Harrison [MVP]

Paul said:
then, why would I get a NullReferenceException when trying to call a C
function:

Unhandled Exception: System.NullReferenceException: Object reference not
set to an instance of an object.
at SXInit(Int32 )

which is defined as:

extern int SXInit(int, ...);

in my C header file. The C header file has many more C functions, and have
problems with them as well, so if
I solve it for one, I will solve it for the others as well.

What are you passing to SXInit? This program works OK:

// Compile with: cl /W4 /clr a.cpp

#using <mscorlib.dll>
using namespace System;

#include <stdio.h>

int main()
{
int x = 2;
printf("%d\n", x);
}
 
P

Paul Brun

Thanks Doug,

The way it works is that I have to pass arguments to the function like the
following:

SXInit(constant1, constant2, NULL);

These constants are defined in the C header file as "#define constant1
2011". And, the
last parameter has to be NULL to signify the end of the list.

The method looks like this:
Int32 MitaiNet::MitaiCtrlr::NET_SXInit(Boolean stdResponseEvent, Boolean
compactMessaging, Boolean multiMonPerDevice)
{
int mitaiResult = 0;
mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE, NULL);
return Int32(mitaiResult);
}

and I call this method from my VB app (my testing application) like so:

Dim ctrlr As New MitaiNet.MitaiCtrlr
Dim result As Integer
result = ctrlr.NET_SXInit(True, False, True)

I need to write a .NET class library to wrap this module. If you need more
info, please let me know

Thanks
Paul
 
D

Doug Harrison [MVP]

Paul said:
Thanks Doug,

The way it works is that I have to pass arguments to the function like the
following:

SXInit(constant1, constant2, NULL);

These constants are defined in the C header file as "#define constant1
2011". And, the
last parameter has to be NULL to signify the end of the list.

If the constants are all ints, shouldn't you pass 0 instead of NULL? The
NULL macro should be used only when you need a null pointer constant, and
even then, it's a bit of a lie, as NULL cannot have a pointer type in C++.
It must be some integral constant zero. This probably isn't your problem,
but it's worth noting.
The method looks like this:
Int32 MitaiNet::MitaiCtrlr::NET_SXInit(Boolean stdResponseEvent, Boolean
compactMessaging, Boolean multiMonPerDevice)
{
int mitaiResult = 0;
mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE, NULL);
return Int32(mitaiResult);
}

and I call this method from my VB app (my testing application) like so:

Dim ctrlr As New MitaiNet.MitaiCtrlr
Dim result As Integer
result = ctrlr.NET_SXInit(True, False, True)

I need to write a .NET class library to wrap this module. If you need more
info, please let me know

I don't see anything obviously wrong there. Do note that arguments passed to
the ellipsis are not type checked and must exactly match what the receiving
function expects. What does SXInit say about the arguments you pass to it?
I'd make sure I got the types right, and that I'm passing the expected
number of arguments.

Here's a little program you can play with that models your situation. Again,
compile with "cl /W4 /clr a.cpp".

#using <mscorlib.dll>
using namespace System;

#include <stdarg.h>
#include <stdio.h>

#pragma unmanaged
extern "C" void f(int x, ...)
{
va_list ap;
va_start(ap, x);
while (int y = va_arg(ap, int))
printf("%d\n", y);
va_end(ap);
}
#pragma managed

public __gc struct A
{
void call_f()
{
f(1, 2, 3, 0);
}
};

int main()
{
A* p = new A;
p->call_f();
}
 
T

Ted Miller

I think it's possible that you have actually gotten into your unmanaged
routine but an (unmanaged) access violation is getting thrown in there for
some reason, and the clr is catching that and translating it into a managed
NullReferenceException. In other words, you might want to assume that it's
not the mechanics of calling your unmanaged routine that's problematic, it's
what the unmanaged routine is doing that is problematic. You should be able
to debug by setting your project for mixed debugging.
 
P

Paul Brun

Thanks for the input.....the API document for the C library states that it
is expecting to see a NULL
at the end of the parameter list. Your program did work in my Studio set
up.....and I understand where
you are coming from, however, the C library is internal to our company and I
have used the API before
in previous C++ applications and I know that the call that I make to SXInit
does work....

I am just curious, what are other obvious reasons for
NullReferenceExceptions???

Paul
 
P

Paul Brun

Where would you set that option?

Paul

Ted Miller said:
I think it's possible that you have actually gotten into your unmanaged
routine but an (unmanaged) access violation is getting thrown in there for
some reason, and the clr is catching that and translating it into a managed
NullReferenceException. In other words, you might want to assume that it's
not the mechanics of calling your unmanaged routine that's problematic, it's
what the unmanaged routine is doing that is problematic. You should be able
to debug by setting your project for mixed debugging.
 
P

Paul Brun

oen thing I noticed, my call stack when debugging in C++.NET instead of
VBApp calling my DLL, shows this as
the call stack when my app runs:
00000000()
mitainet.dll!MitaiNet.MitaiCtrlr.NET_SXInit(bool stdResponseEvent = true,
bool compactMessaging = false, bool multiMonPerDevice = true) Line 12 + 0x17
bytes C++
MitaiVBAppExample.exe!MitaiVBAppExample.Form1.Button1_Click(Object sender
= {System.Windows.Forms.Button}, System.EventArgs e = {System.EventArgs})
Line 66 + 0x13 bytes Basic
 
D

Doug Harrison [MVP]

Paul said:
Thanks for the input.....the API document for the C library states that it
is expecting to see a NULL
at the end of the parameter list. Your program did work in my Studio set
up.....and I understand where
you are coming from, however, the C library is internal to our company and I
have used the API before
in previous C++ applications and I know that the call that I make to SXInit
does work....

I am just curious, what are other obvious reasons for
NullReferenceExceptions???

I have no idea what could be causing it. See if Ted Miller's debugging
suggestions help. You need to determine who's throwing the exception. I
assume it isn't thrown if you stub out the SXInit call?
 
P

Paul Brun

Well...well...well...it is not the datatypes in question, but it seems like
the compilation is not properly translation the method pointer
correctly. When I expand to disassembly mode, I get the following for the
SXInit call in a regular C++ application (moving args
as it is not important):

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE,
NULL);
0048C1B8 push 0
0048C1BA push 835h
0048C1BF push 834h
0048C1C4 call @ILT+6950(_SXInit) (482B2Bh)
0048C1C9 add esp,0Ch
0048C1CC mov dword ptr [mitaiResult],eax

This is what it looks like in my .NET application:

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE, NULL);
00000012 push 834h
00000017 push 835h
0000001c push 0
0000001e push 18FFA8h
00000023 call dword ptr ds:[008F6A50h]
00000029 add esp,10h
0000002c mov edi,eax
0000002e mov esi,edi

So, it seems like the call to the function was not translated correctly as
the null reference exception occurs on the "call" line...

Any ideas how to have C functions translated to assembly correctly, or does
this not really matter as the disassembly will
almost always look different?

Paul
 
P

Paul Brun

read my response to my original post as it addresses some points relating to
the disassembly view...it might prove to be useful.
Please let me know.
Thanks
Paul
 
P

Paul Brun

that is not it either. I did a simple Managed C++ Console applicaiton and
made the same function calls with the same constants
including "NULL" and the call pointer in the assembly appeared similar to
the one I pasted below....and it worked....there
appears to be something that is not working correctly with the way the
project settings are set for the .NET Class Library.

I hope that it is not the inevitable Mixed Mode DLL bug....

Paul


Paul Brun said:
Well...well...well...it is not the datatypes in question, but it seems like
the compilation is not properly translation the method pointer
correctly. When I expand to disassembly mode, I get the following for the
SXInit call in a regular C++ application (moving args
as it is not important):

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE,
NULL);
0048C1B8 push 0
0048C1BA push 835h
0048C1BF push 834h
0048C1C4 call @ILT+6950(_SXInit) (482B2Bh)
0048C1C9 add esp,0Ch
0048C1CC mov dword ptr [mitaiResult],eax

This is what it looks like in my .NET application:

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE, NULL);
00000012 push 834h
00000017 push 835h
0000001c push 0
0000001e push 18FFA8h
00000023 call dword ptr ds:[008F6A50h]
00000029 add esp,10h
0000002c mov edi,eax
0000002e mov esi,edi

So, it seems like the call to the function was not translated correctly as
the null reference exception occurs on the "call" line...

Any ideas how to have C functions translated to assembly correctly, or does
this not really matter as the disassembly will
almost always look different?

Paul






Paul Brun said:
Can this be done? Is there a way to "de-alias" the int datatype so I can
pass an int into a C method??

Paul
 
T

Ted Miller

The call instruction in the .Net case below is an indirect call -- did you
examine the dword at 8F6A50 before the call instruction executed? Was it
valid? Just guessing that the exception appears to be on the call
instruction because you tried to step *over* it instead of *into* it, and
that you are getting into your unmanaged routine just fine.

AFAIK, the mixed mode dll issue wouldn't manifest itself this way.

To change the debugging type, bring up the properties for the project and
look at Debugging, you should see a "Debugger Type" with options for Auto,
Native Only, Managed Only, and Mixed. Beware that mixed mode debugging can
be considerably slower and thus more painful (seems to be much more
resource-intensive behind the scenes), but it can useful in this sort of
situation.

Paul Brun said:
that is not it either. I did a simple Managed C++ Console applicaiton and
made the same function calls with the same constants
including "NULL" and the call pointer in the assembly appeared similar to
the one I pasted below....and it worked....there
appears to be something that is not working correctly with the way the
project settings are set for the .NET Class Library.

I hope that it is not the inevitable Mixed Mode DLL bug....

Paul


Paul Brun said:
Well...well...well...it is not the datatypes in question, but it seems like
the compilation is not properly translation the method pointer
correctly. When I expand to disassembly mode, I get the following for the
SXInit call in a regular C++ application (moving args
as it is not important):

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE,
NULL);
0048C1B8 push 0
0048C1BA push 835h
0048C1BF push 834h
0048C1C4 call @ILT+6950(_SXInit) (482B2Bh)
0048C1C9 add esp,0Ch
0048C1CC mov dword ptr [mitaiResult],eax

This is what it looks like in my .NET application:

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE, NULL);
00000012 push 834h
00000017 push 835h
0000001c push 0
0000001e push 18FFA8h
00000023 call dword ptr ds:[008F6A50h]
00000029 add esp,10h
0000002c mov edi,eax
0000002e mov esi,edi

So, it seems like the call to the function was not translated correctly as
the null reference exception occurs on the "call" line...

Any ideas how to have C functions translated to assembly correctly, or does
this not really matter as the disassembly will
almost always look different?

Paul






Paul Brun said:
Can this be done? Is there a way to "de-alias" the int datatype so I can
pass an int into a C method??

Paul
 
P

Paul Brun

I will look into this a bit more as I have both my test app and my actual
..NET Class library up and
running......is there anyway to find out what the "DS" is referencing, or is
the method actually located
at the memory reference (in this case 8F6A50)???

Paul

Ted Miller said:
The call instruction in the .Net case below is an indirect call -- did you
examine the dword at 8F6A50 before the call instruction executed? Was it
valid? Just guessing that the exception appears to be on the call
instruction because you tried to step *over* it instead of *into* it, and
that you are getting into your unmanaged routine just fine.

AFAIK, the mixed mode dll issue wouldn't manifest itself this way.

To change the debugging type, bring up the properties for the project and
look at Debugging, you should see a "Debugger Type" with options for Auto,
Native Only, Managed Only, and Mixed. Beware that mixed mode debugging can
be considerably slower and thus more painful (seems to be much more
resource-intensive behind the scenes), but it can useful in this sort of
situation.

Paul Brun said:
that is not it either. I did a simple Managed C++ Console applicaiton and
made the same function calls with the same constants
including "NULL" and the call pointer in the assembly appeared similar to
the one I pasted below....and it worked....there
appears to be something that is not working correctly with the way the
project settings are set for the .NET Class Library.

I hope that it is not the inevitable Mixed Mode DLL bug....

Paul


Paul Brun said:
Well...well...well...it is not the datatypes in question, but it seems like
the compilation is not properly translation the method pointer
correctly. When I expand to disassembly mode, I get the following for the
SXInit call in a regular C++ application (moving args
as it is not important):

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE,
NULL);
0048C1B8 push 0
0048C1BA push 835h
0048C1BF push 834h
0048C1C4 call @ILT+6950(_SXInit) (482B2Bh)
0048C1C9 add esp,0Ch
0048C1CC mov dword ptr [mitaiResult],eax

This is what it looks like in my .NET application:

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE, NULL);
00000012 push 834h
00000017 push 835h
0000001c push 0
0000001e push 18FFA8h
00000023 call dword ptr ds:[008F6A50h]
00000029 add esp,10h
0000002c mov edi,eax
0000002e mov esi,edi

So, it seems like the call to the function was not translated
correctly
 
P

Paul Brun

it has to be something specific to the call itself as it doesn't even step
into the function. I tried the same debug library with my
test app and I was able to step into the method and see the source code
without any problems. I can't do that with my .NET
Class Library DLL when doing the same thing in debug mode....

The front end to my .NET Class Library DLL is a VB Test app which access my
DLL from the development location.

Thanks
Paul

Paul Brun said:
I will look into this a bit more as I have both my test app and my actual
.NET Class library up and
running......is there anyway to find out what the "DS" is referencing, or is
the method actually located
at the memory reference (in this case 8F6A50)???

Paul

Ted Miller said:
The call instruction in the .Net case below is an indirect call -- did you
examine the dword at 8F6A50 before the call instruction executed? Was it
valid? Just guessing that the exception appears to be on the call
instruction because you tried to step *over* it instead of *into* it, and
that you are getting into your unmanaged routine just fine.

AFAIK, the mixed mode dll issue wouldn't manifest itself this way.

To change the debugging type, bring up the properties for the project and
look at Debugging, you should see a "Debugger Type" with options for Auto,
Native Only, Managed Only, and Mixed. Beware that mixed mode debugging can
be considerably slower and thus more painful (seems to be much more
resource-intensive behind the scenes), but it can useful in this sort of
situation.

Paul Brun said:
that is not it either. I did a simple Managed C++ Console applicaiton and
made the same function calls with the same constants
including "NULL" and the call pointer in the assembly appeared similar to
the one I pasted below....and it worked....there
appears to be something that is not working correctly with the way the
project settings are set for the .NET Class Library.

I hope that it is not the inevitable Mixed Mode DLL bug....

Paul


Well...well...well...it is not the datatypes in question, but it seems
like
the compilation is not properly translation the method pointer
correctly. When I expand to disassembly mode, I get the following
for
the
SXInit call in a regular C++ application (moving args
as it is not important):

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE,
NULL);
0048C1B8 push 0
0048C1BA push 835h
0048C1BF push 834h
0048C1C4 call @ILT+6950(_SXInit) (482B2Bh)
0048C1C9 add esp,0Ch
0048C1CC mov dword ptr [mitaiResult],eax

This is what it looks like in my .NET application:

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE, NULL);
00000012 push 834h
00000017 push 835h
0000001c push 0
0000001e push 18FFA8h
00000023 call dword ptr ds:[008F6A50h]
00000029 add esp,10h
0000002c mov edi,eax
0000002e mov esi,edi

So, it seems like the call to the function was not translated
correctly
as
the null reference exception occurs on the "call" line...

Any ideas how to have C functions translated to assembly correctly, or
does
this not really matter as the disassembly will
almost always look different?

Paul






Can this be done? Is there a way to "de-alias" the int datatype so
I
can
pass an int into a C method??

Paul
 
P

Paul Brun

nevermind....you are correct....I was not linking in the debug libraries
correctly and am not able to
step inside the code.....now I know what it is crashing, but don't know why
yet....getting closer and
closer.

Thanks
Ted Miller said:
The call instruction in the .Net case below is an indirect call -- did you
examine the dword at 8F6A50 before the call instruction executed? Was it
valid? Just guessing that the exception appears to be on the call
instruction because you tried to step *over* it instead of *into* it, and
that you are getting into your unmanaged routine just fine.

AFAIK, the mixed mode dll issue wouldn't manifest itself this way.

To change the debugging type, bring up the properties for the project and
look at Debugging, you should see a "Debugger Type" with options for Auto,
Native Only, Managed Only, and Mixed. Beware that mixed mode debugging can
be considerably slower and thus more painful (seems to be much more
resource-intensive behind the scenes), but it can useful in this sort of
situation.

Paul Brun said:
that is not it either. I did a simple Managed C++ Console applicaiton and
made the same function calls with the same constants
including "NULL" and the call pointer in the assembly appeared similar to
the one I pasted below....and it worked....there
appears to be something that is not working correctly with the way the
project settings are set for the .NET Class Library.

I hope that it is not the inevitable Mixed Mode DLL bug....

Paul


Paul Brun said:
Well...well...well...it is not the datatypes in question, but it seems like
the compilation is not properly translation the method pointer
correctly. When I expand to disassembly mode, I get the following for the
SXInit call in a regular C++ application (moving args
as it is not important):

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE,
NULL);
0048C1B8 push 0
0048C1BA push 835h
0048C1BF push 834h
0048C1C4 call @ILT+6950(_SXInit) (482B2Bh)
0048C1C9 add esp,0Ch
0048C1CC mov dword ptr [mitaiResult],eax

This is what it looks like in my .NET application:

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE, NULL);
00000012 push 834h
00000017 push 835h
0000001c push 0
0000001e push 18FFA8h
00000023 call dword ptr ds:[008F6A50h]
00000029 add esp,10h
0000002c mov edi,eax
0000002e mov esi,edi

So, it seems like the call to the function was not translated
correctly
 
P

Paul Brun

please see new thread: Null Reference Exception on strtok function - NEW
POST

Paul

Paul Brun said:
nevermind....you are correct....I was not linking in the debug libraries
correctly and am not able to
step inside the code.....now I know what it is crashing, but don't know why
yet....getting closer and
closer.

Thanks
Ted Miller said:
The call instruction in the .Net case below is an indirect call -- did you
examine the dword at 8F6A50 before the call instruction executed? Was it
valid? Just guessing that the exception appears to be on the call
instruction because you tried to step *over* it instead of *into* it, and
that you are getting into your unmanaged routine just fine.

AFAIK, the mixed mode dll issue wouldn't manifest itself this way.

To change the debugging type, bring up the properties for the project and
look at Debugging, you should see a "Debugger Type" with options for Auto,
Native Only, Managed Only, and Mixed. Beware that mixed mode debugging can
be considerably slower and thus more painful (seems to be much more
resource-intensive behind the scenes), but it can useful in this sort of
situation.

Paul Brun said:
that is not it either. I did a simple Managed C++ Console applicaiton and
made the same function calls with the same constants
including "NULL" and the call pointer in the assembly appeared similar to
the one I pasted below....and it worked....there
appears to be something that is not working correctly with the way the
project settings are set for the .NET Class Library.

I hope that it is not the inevitable Mixed Mode DLL bug....

Paul


Well...well...well...it is not the datatypes in question, but it seems
like
the compilation is not properly translation the method pointer
correctly. When I expand to disassembly mode, I get the following
for
the
SXInit call in a regular C++ application (moving args
as it is not important):

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE,
NULL);
0048C1B8 push 0
0048C1BA push 835h
0048C1BF push 834h
0048C1C4 call @ILT+6950(_SXInit) (482B2Bh)
0048C1C9 add esp,0Ch
0048C1CC mov dword ptr [mitaiResult],eax

This is what it looks like in my .NET application:

mitaiResult = SXInit(SX_STANDARD_CMD_RESPONSE_EVENT,
SX_MULTIPLE_MONITORS_PER_DEVICE, NULL);
00000012 push 834h
00000017 push 835h
0000001c push 0
0000001e push 18FFA8h
00000023 call dword ptr ds:[008F6A50h]
00000029 add esp,10h
0000002c mov edi,eax
0000002e mov esi,edi

So, it seems like the call to the function was not translated
correctly
as
the null reference exception occurs on the "call" line...

Any ideas how to have C functions translated to assembly correctly, or
does
this not really matter as the disassembly will
almost always look different?

Paul






Can this be done? Is there a way to "de-alias" the int datatype so
I
can
pass an int into a C method??

Paul
 

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