I encounter a strange problem using platform invoke using C#.
The senario is this:
I have a dll which uses a 3rd party static link library (lib). Inside the lib, there are some C structures defined by not exposed to user, in the dll, that data type can be treated as an opaque type.
I use C# and unamanaged C++ to write two programs to use the dll. The C++ version works perfectly, but the C# version always get some exception (Object reference not set to an instance of an object)
Here's some demo code:
(1)In 3rd party lib file, there's one type
//_tagContext's internal structre unknown, it's an opaque type
typedef _tagContext * tagContext;
(2)In my dll file there are 2 functions:
//Create an opaque type object to let ptagContext point to it
int Init(tagContext* ptagContext, int* status);
//Do some work using the context initialized by Init()
int DoWork(tagContext context, char* data);
(3)In my C++ code:
//Declare a opaque type variable
//Declare a variable of the opaque type
tagContext* ptagContext= 0;
int status = 0;
//Init, works fine
Init(ptagContext, &status);
//Do work, works fine
DoWork(*ptagContext, data);
(4)In my C# code:
public class MyClass
{
private System.IntPtr context;
private int status;
public int Initialize()
{
MyApi.Init(out context, out status);
}
public int Work(String data)
{
MyApi.DoWork(context, data);
}
private class MyApi
{
[DllImport("MyApi.dll", CharSet = CharSet.Ansi)]
public static extern int Init(out System.IntPtr context, out int status);
[DllImport("MyApi.dll", CharSet = CharSet.Ansi)]
public static extern int DoWork(System.IntPtr context, String data);
}
}
The user of this class:
MyClass c = new MyClass();
String data = new String("data");
//Works fine, can see the context field inside MyClass is initialized
c.Init();
//Throw exception: Object reference not set to an instance of an object
c.Work(data);
I have no idea what's going on after CLR calls Init() to initialize IntPtr.
Is a unmanaged object created and pointed to by IntPtr?
Where is the unmanaged object created? Heap or stack?
After the c.Init() finish, is it possible for the unmanaged object (refeced by IntPtr) to be garbage collected,
so when I call c.Work() it shows me the exception?
Experts please help out! Thanks so much in advance!