2

我在 C 文件中有一个结构,如下所示

struct Parameter{
    char param1[20];
    char param2[20];
}

以及 C 文件中的一个函数,该函数将此结构作为参数以及 char* 作为另一个参数,如下所示

extern "C" __declspec(dllexport) void GetValue(char* opt,struct Parameter param);
void GetValue(char* opt, struct Parameter params)
{
printf("%s", params->param1);
}

我想使用编组从我的 C# 应用程序中调用它。我在 C# 中创建了一个类似的结构

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class Parameters
{      
    public string Param1 { get; set; }     
    public string Param1 { get; set; }   
}

并使用以下方法在 C# 中调用它

 [DllImport(@"C:\Test\CTestDll.dll",CallingConvention = CallingConvention.Cdecl,CharSet=CharSet.Ansi)]      
 public static extern void GetValue([MarshalAs(UnmanagedType.LPStr)]StringBuilder sbOut, [MarshalAs(UnmanagedType.LPStruct)]Parameters sbIn);

但是打印语句的结果是打印 null。我在 C 编程方面不是很好。请帮我整理一下。我错了,是在 C 函数中还是从 C# 编组

4

1 回答 1

2

不同之处在于,在 C++ 中,您的结构包含原始字符,而在 C# 中,您的类包含对字符串的引用。MarshalAs 属性将使用 char 数组而不是对字符串的引用:

unsafe static class Program
{

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Parameters
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public String Param1;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public String Param2;
}


[DllImport(@"CTestDll2.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void GetValue(StringBuilder sbOut, Parameters sbIn);


static void Main(string[] args)
{
    var p = new Parameters
    {
        Param1 = "abc",
        Param2 = "dfc"
    };

    var s = new StringBuilder("some text");

    GetValue(s, p);
}

}

C++:

// CTestDll.h

#pragma once

#include <stdio.h>

extern "C" __declspec(dllexport) void GetValue(char* opt, struct Parameter param);

struct Parameter{
    char param1[20];
    char param2[20];
};

void GetValue(char* opt, struct Parameter params)
{
    printf("param1: %s, param2: %s, string: %s", params.param1, params.param2, opt);
}
于 2012-07-13T13:00:08.900 回答