Reputation: 103
Hy all,
I want to make from a unmanaged dll to a managed dll in C#.
in the documentation it is:
typedef void* AP_HANDLE
typedef uint32_t ap_u32
AP_HANDLE ap_CreateVirtual(const char *szFilename)
void ap_SetState(AP_HANDLE apbase, const char *szState, int nValue)
unsigned char *ap_ColorPipe(AP_HANDLE apbase,
unsigned char *pInBuffer,
ap_u32 nInBufferSize,
ap_u32 *rgbWidth,
ap_u32 *rgbHeight,
ap_u32 *rgbBitDepth)
In C++ works fine, but in C# the syntax is the problem It seems I can't make not evan the first function work
public unsafe class appbase
{
[DllImport("D:\\apbase.dll", EntryPoint = "ap_CreateVirtual")]
//, CharSet = UnicodeEncoding
//, CallingConvention = CallingConvention.StdCall
public static extern void* ap_CreateVirtual(char* szFilename);
}
and
public static void Main()
{
unsafe
{
void* ap_handle = null;
appbase APPbase = new appbase();
string s = "D:\\ASX.xsdat";
fixed (char* p = s)
{
ap_handle = APPbase.ap_CreateVirtual(p);
}
return;
}
}
tried with argument for ap_CreateVirtual string, String*, char*, char[] and put a break point on return; the ap_handle was always with value 0x0000
what is the proper way to import these functions ?
Upvotes: 0
Views: 2511
Reputation: 63732
Just copying over the C++ headers isn't enough. You need to understand what the arguments actually mean and how they are represented. The first function is simple enough:
[DllImport("...", EntryPoint="ap_CreateVirtual")]
public static extern IntPtr ap_CreateVirtual(
[In, MarshalAs(UnmanagedType.LPStr)] string szFilename);
I assume that in the second, szState
is again a simple LPStr, while the pInBuffer
is most likely a fixed-length byte[]
with size determined by nInBufferSize
. rgbXXX
seem to be ref
arguments. The return type may again be a LPStr.
Upvotes: 0
Reputation: 283674
char*
is the default marshaling for a .NET string.
[DllImport("D:\\apbase.dll", EntryPoint = "ap_CreateVirtual", CharSet = CharSet.Ansi)]
//, CallingConvention = CallingConvention.StdCall
public static extern System.IntPtr ap_CreateVirtual(string szFilename);
Your original attempt was wrong because char
in C# is C++'s wchar_t
, not C++ char
.
If you need a C++ char
in C#, it's either byte
or sbyte
. But p/invoke will simply do the right thing with System.String
.
Upvotes: 2