I am wring a .NET app to call an unmanaged DLL(Unicode).
Below is the header for the unmanaged DLL:
#pragma once
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
// Callback function for ProcessFileAPI. The function is called whenever progress advances.
typedef VOID (CALLBACK* LPPROGRESSPROC)(CONST BYTE btProgress, LPVOID lParam);
#pragma pack(1)
// Options for ProcessFileAPI
typedef struct _OPTIONS1
{
BOOL m_bOption1;
BOOL m_bOption2;
} OPTIONS1, *LPOPTIONS1;
#pragma pack()
DWORD WINAPI ProcessFileAPI(LPCTSTR lpSrcFileName, LPCTSTR lpDstFileName, LPPROGRESSPROC lpProgressProc, LPVOID lpProgProcParam,
LPBOOL pbCancel, CONST LPOPTIONS1 lpOptions1);
#ifdef __cplusplus
}
#endif
And the .cpp for unmanaged DLL:
extern "C" DWORD WINAPI ProcessFileAPI(LPCTSTR lpSrcFileName, LPCTSTR lpDstFileName, LPPROGRESSPROC lpProgressProc, LPVOID lpProgProcParam,
LPBOOL pbCancel, CONST LPOPTIONS1 lpOptions1)
{
TRACE(_T("SrcFileName: %s. DstFileName: %s."), lpSrcFileName, lpDstFileName);
return 0;
}
Below is the .NET code for the function:
using System;
using System.Runtime.InteropServices;
namespace SDKAPI
{
public struct TOptions1
{
public bool bOption1;
public bool bOption2;
} // end TOptions1
public delegate void TProgressProc(byte btProgress, IntPtr lParam);
}
namespace SDKAPI.Units
{
public class SDKAPI
{
[DllImport("SDK.DLL")]
public static extern uint ProcessFileAPI(string lpSrcFileName, string lpDstFileName, TProgressProc pgrsproc, IntPtr lpProgProcParam, ref int pbCancel, ref TOptions1 options);
} // end SDKAPI
}
And below is the calling of the function:
Options1.bOption1 = true;
Options1.bOption2 = false;
// Process the file
FCancel = 0;
RetCode = SDKAPI.Units.SDKAPI.ProcessFileAPI(txtSrcFile.Text, txtDstFile.Text, new SDKAPI.TProgressProc(this.ProgressProc), IntPtr.Zero, ref FCancel, ref Options1);
When calling the DLL with txtSrcFile.Text = "a"
and txtDstFile.Text = "b"
, but I debug in the DLL and find the parameter lpSrcFileName
becomes "a"
then followed with many strange characters. Why?
You need to find out whether the unmanaged DLL is using Unicode or not. If yes you need CharSet.Unicode
otherwise CharSet.Ansi
.
You also need to set the pack.
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct TOptions1
{
public bool bOption1;
public bool bOption2;
}
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void TProgressProc(byte btProgress, IntPtr lParam);
[DllImport("SDK.DLL", CharSet = CharSet.Unicode)]
public static extern uint ProcessFileAPI(
string lpSrcFileName, string lpDstFileName, TProgressProc pgrsproc,
IntPtr lpProgProcParam, ref bool pbCancel, [In] in TOptions1 options);