如何用C#中的Struct作为参数调用C代码中的函数

时间:2012-07-13 12:42:04

标签: c# c marshalling

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

但是作为print语句的结果是打印null。我在C编程方面不是很好。请帮我解决一下。我错了,是C函数还是C#编组

1 个答案:

答案 0 :(得分:2)

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

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