如何使用结构作为包含字符串的参数进行互操作调用

发布于 2024-12-02 06:19:51 字数 1204 浏览 0 评论 0原文

我试图通过互操作从 C# 调用 DLL 中的 C++ 函数。 DLL是别人写的。函数签名如下:

AXI_DLL_EXPORT int __stdcall GetFileType(StringParam *stringParam, int *fileType)

StringParam 是一个结构体,定义如下:

struct StringParam
{
    int size;    // 4 byte integer for the size of the string buffer
    LPWSTR buff; // Pointer to a wide char buffer
}

该结构体用于来回传递字符串。它可以用作输入和输出参数。结构中大小字段的用途主要是将字符串返回给调用者并指示所需缓冲区的大小。如果缓冲区的大小(由调用者提供)太小而无法容纳字符串,则调用者可以收到通知,然后可以在对该函数的连续调用中提供更大的缓冲区。

在 C# 中,我创建了一个相应的结构,如下所示:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct StringParam
{
    public int Size;

    [MarshalAs(UnmanagedType.LPWStr)]
    public string Text;

    public StringParam(string text)
    {
        this.Text = text;
        this.Size = text.Length;
    }
}

我按如下方式声明了 DllImport 函数调用:

[DllImport("Custom.dll", CharSet = CharSet.Unicode)]
public static extern int GetFileType(StringParam stringParam, out int fileType);

调用失败并出现以下错误:

对 PInvoke 函数“... GetFileType”的调用使堆栈不平衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。

我应该如何声明结构并从 C# 调用本机函数?

I am attempting to call a C++ function in a DLL from C# via interop. The DLL was written by someone else. The function signature is as follows:

AXI_DLL_EXPORT int __stdcall GetFileType(StringParam *stringParam, int *fileType)

StringParam is a struct defined as follows:

struct StringParam
{
    int size;    // 4 byte integer for the size of the string buffer
    LPWSTR buff; // Pointer to a wide char buffer
}

This struct is used for passing strings back and forth. It can be used as both in and out parameters. The purpose of the size field in the struct is primarily for returning strings to the caller and to indicate the size of the buffer required. If the size of the buffer (provided by the caller) is too small to hold the string the caller can be informed of this and can then provide a larger buffer in a successive call to the function.

In C# I created a corresponding struct as follows:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct StringParam
{
    public int Size;

    [MarshalAs(UnmanagedType.LPWStr)]
    public string Text;

    public StringParam(string text)
    {
        this.Text = text;
        this.Size = text.Length;
    }
}

I declared the DllImport function call as follows:

[DllImport("Custom.dll", CharSet = CharSet.Unicode)]
public static extern int GetFileType(StringParam stringParam, out int fileType);

The call fails with the following error:

A call to PInvoke function '... GetFileType' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

How should I declare the struct and call the native function from C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

在梵高的星空下 2024-12-09 06:19:51
public static extern int GetFileType(ref StringParam stringParam, out int fileType); 
public static extern int GetFileType(ref StringParam stringParam, out int fileType); 
远山浅 2024-12-09 06:19:51

你尝试过吗:

[DllImport("Custom.dll", CharSet = CharSet.Unicode)]
public static extern int GetFileType(StringParam stringParam, ref int fileType);

我认为你必须在 pInvoke 之前固定 ref int 。

Have you tried :

[DllImport("Custom.dll", CharSet = CharSet.Unicode)]
public static extern int GetFileType(StringParam stringParam, ref int fileType);

And I think you have to pin the ref int before you pInvoke.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文