从C#向C DLL传递字符串

4

我在使用c#应用程序中的c dll时遇到了一些麻烦。导致错误的函数在dll的头文件中被定义如下:

int __stdcall DDC_CreateFilePropertyString (DDCFileHandle file, 
                                        const char *property,
                                        const char *value);

我在访问dll的类中添加了以下代码。
[DllImport("nilibddc.dll", CallingConvention = CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
private static extern int DDC_CreateFilePropertyString(IntPtr file,
                         [MarshalAs(UnmanagedType.LPStr)]string property,
                         [MarshalAs(UnmanagedType.LPStr)]string value);

Type DDCFileHandle在头文件中定义如下:

typedef struct _DDCFile DDCFile;
typedef DDCFile*    DDCFileHandle;

头文件中没有有关_DDCFile结构的其他信息(我没有使用库的其他文件)。

在调用函数DDC_CreateFilePropertyString()之前,我调用以下函数创建文件并获取文件句柄。

[DllImport("nilibddc.dll", CallingConvention = CallingConvention.Cdecl, CharSet=CharSet.Ansi]
private static extern int DDC_CreateFile(char[] filePath,
                          char[] fileType,
                          char[] name,
                          char[] description,
                          char[] title,
                          char[] author,
                          ref IntPtr file);

头文件中的定义如下所示。
int __stdcall DDC_CreateFile (const char *filePath,
                          const char *fileType,
                          const char *name,
                          const char *description,
                          const char *title,
                          const char *author,
                          DDCFileHandle *file);

现在每次我调用函数DDC_CreateFilePropertyString时,它都会返回一个错误,告诉我传递了一些错误的参数。我做错了什么?我使用的库是National Instruments的TDMS C API。
谢谢您的帮助。

1
调用DDC_CreateFile是否成功?你怎么知道?它的const char *参数不应该像DDC_CreateFilePropertyHandle一样作为string而不是char[]传递吗?由于您的DLL函数也声明为stdcall,因此您将不得不在pinvoke声明中更改cdecl调用约定。 - anton.burger
是的,它确实成功了。返回代码是正常的。如果我只调用“DDC_CreateFile”函数,它会在文件系统中正确地创建文件。我将“char []”更改为“string”,并将“cdec1”更改为“stdcall”,但仍然出现错误。 - Devkev
1个回答

2

您的p/invokes有点问题。您需要使用CallingConvention.Stdcall,这是默认设置。对于const char*参数,您应该在C#端将它们声明为string

DDC_CreateFile的正确C# p/invoke如下:

[DllImport("nilibddc.dll", CharSet=CharSet.Ansi]
private static extern int DDC_CreateFile(
    string filePath,
    string fileType,
    string name,
    string description,
    string title,
    string author,
    ref IntPtr file
);

对于DDC_CreateFilePropertyString,您需要这样做:

[DllImport("nilibddc.dll", CharSet=CharSet.Ansi)]
private static extern int DDC_CreateFilePropertyString(
    IntPtr file,
    string property,
    string value
);

如果在修复代码后,调用这些函数仍然出现错误,那么显然您正在错误地使用库。这已超出了本问题的范围。请查阅文档并/或向库供应商寻求支持。

非常感谢您的帮助!我尝试了但没有成功。我得联系供应商。谢谢! - Devkev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接