.NET应用程序调用未管理的DLL,参数包含奇怪的字符

问题描述 投票:0回答:1

我正在编写一个 .NET 应用程序来调用非托管 DLL。

下面是非托管 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

以及非托管 DLL 的 .cpp:

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;
}

以下是该函数的 .NET 代码:

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
}

下面是函数的调用:

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);

txtSrcFile.Text = "a"
txtDstFile.Text = "b"
调用DLL时,但我在DLL中调试,发现参数
lpSrcFileName
变成了
"a"
,后面跟着很多奇怪的字符。为什么?

c# c++ string dll pinvoke
1个回答
0
投票

您需要查明非托管DLL是否使用Unicode。如果是,您需要

CharSet.Unicode
,否则
CharSet.Ansi

您还需要在

bool
s

上设置包装和编组
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct TOptions1
{
    [MarshalAs(UnmanagedType.I1)]
    public bool bOption1;
    [MarshalAs(UnmanagedType.I1)]
    public bool bOption2;
}

[UnmanagedFunctionPointer]
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, [MarshalAs(UnmanagedType.I1)] ref bool pbCancel,
    [In] in TOptions1 options);
© www.soinside.com 2019 - 2024. All rights reserved.