Thanks again!
After doing a research I got the same answer, and I think that's the best. But I haven't been explicit enough. The fact is that I can't add such wrapper function returning something more suitable like
char* because I don't have the DLL code.
There's a way to instantiate a C++ class from a DLL. You can call a function that returns a pointer such as a class constructor (returns
this). Then in C# you have to declare a struct that properly holds the
this pointer:
-
[StructLayout(LayoutKind.Sequential, Pack = 4)]
-
public unsafe struct __CString
-
{
-
public IntPtr* _vtable;
-
public int m_Value;
-
}
-
Then you can make a C# wrapper class for the C++ class CString:
-
public unsafe class CString : IDisposable
-
{
-
private __CString* _cpp;
-
-
[DllImport("mfc42.dll", EntryPoint = "#535", CallingConvention = CallingConvention.ThisCall)]
-
private static extern int _CString_Constructor(__CString* ths, CString str);
-
-
[DllImport("mfc42.dll", EntryPoint = "#537", CallingConvention = CallingConvention.ThisCall)]
-
private static extern int _CString_Constructor(__CString* ths, [MarshalAs(UnmanagedType.LPStr)] String str);
-
-
[DllImport("mfc42.dll", EntryPoint = "#540", CallingConvention = CallingConvention.ThisCall)]
-
private static extern int _CString_Constructor(__CString* ths);
-
-
[DllImport("mfc42.dll", EntryPoint = "#800", CallingConvention = CallingConvention.ThisCall)]
-
private static extern void _CString_Destructor(__CString* ths);
-
-
[DllImport("mfc42.dll", EntryPoint = "#2915", CallingConvention = CallingConvention.ThisCall)]
-
[return: MarshalAs(UnmanagedType.LPStr)]
-
private static extern String _CString_GetBuffer(__CString* ths, int Length);
-
-
public CString(CString str)
-
{
-
_cpp = (__CString*)Memory.Alloc(sizeof(__CString));
-
_CString_Constructor(_cpp, str);
-
}
-
-
public CString(String str)
-
{
-
_cpp = (__CString*)Memory.Alloc(sizeof(__CString));
-
_CString_Constructor(_cpp, str);
-
}
-
-
public CString()
-
{
-
_cpp = (__CString*)Memory.Alloc(sizeof(__CString));
-
_CString_Constructor(_cpp);
-
}
-
-
public void Dispose()
-
{
-
_CString_Destructor(_cpp);
-
Memory.Free(_cpp);
-
}
-
-
public String GetBuffer()
-
{
-
return _CString_GetBuffer(_cpp, 255);
-
}
-
}
-
Actually, I can instatiate a CString in this way without any problems:
-
class Program
-
{
-
static void Main(string[] args)
-
{
-
CString s = new CString("Hello, World!");
-
Console.WriteLine(s.GetBuffer());
-
}
-
}
-
But when I try to do this:
-
class Program
-
{
-
static void Main(string[] args)
-
{
-
Sample s = new Sample(1000);
-
Console.WriteLine(s.AsString().GetBuffer());
-
}
-
}
-
-
/*
-
CString code...
-
*/
-
-
/*
-
Sample Class Wrapper
-
*/
-
-
[StructLayout(LayoutKind.Sequential, Pack = 4)]
-
public unsafe struct __Sample
-
{
-
public IntPtr* _vtable;
-
public int m_Value;
-
}
-
-
public unsafe class Sample : IDisposable
-
{
-
private __Sample* _cpp;
-
-
[DllImport("OldMFC.dll", EntryPoint = "??0Sample@@QAE@H@Z", CallingConvention = CallingConvention.ThisCall)]
-
private static extern int _Sample_Constructor(__Sample* ths, int Value);
-
-
[DllImport("OldMFC.dll", EntryPoint = "??1Sample@@UAE@XZ", CallingConvention = CallingConvention.ThisCall)]
-
private static extern void _Sample_Destructor(__Sample* ths);
-
-
[DllImport("OldMFC.dll", EntryPoint = "?AsString@Sample@@QAEAAVCString@@XZ", CallingConvention = CallingConvention.ThisCall)]
-
private static extern CString _Sample_AsString(__Sample* ths);
-
-
[DllImport("OldMFC.dll", EntryPoint = "?GetValue@Sample@@QAEHXZ", CallingConvention = CallingConvention.ThisCall)]
-
private static extern int _Sample_GetValue(__Sample* ths);
-
-
public Sample(int Value)
-
{
-
_cpp = (__Sample*)Memory.Alloc(sizeof(__Sample));
-
_Sample_Constructor(_cpp, Value);
-
}
-
-
public void Dispose()
-
{
-
_Sample_Destructor(_cpp);
-
Memory.Free(_cpp);
-
}
-
-
public CString AsString()
-
{
-
return _Sample_AsString(_cpp);
-
}
-
}
-
-
/*
-
Memory Class code...
-
*/
-
I get this error:
Quote:
Unspecied error
Exception from HRESULT: 0x80004005 (E_FAIL)
The DLL function declaration is:
Quote:
CString & Sample::AsString();
Any idea about it?
Alex G.