C#中LPCTSTR *的等价性是什么?

时间:2014-03-26 05:55:54

标签: c# marshalling

我有一个非托管C ++函数驻留在我从C#应用程序调用的Dll中。这是函数的签名:

GetCrashMeasurement(LPCTSTR channelName, LPCTSTR properties, LPCTSTR * Values, HANDLE error)

其中channelNameproperties是输入参数[in];并且Values是输出参数[out]。

我也在使用C#应用程序中的Platform调用,如下所示:

[DllImport("DrvCrashHAL.dll", EntryPoint = "coCRAL_GetCrashMeasurements")]

public static unsafe extern CoStatus GetCrashMeasurements(string sChannel, string sMeasurements, ref string sValues, IntPtr hError);

从我的C#应用​​程序中,我按以下方式调用该函数:

string Text = "";
intptr herror = intptr.zero;
GetCrashMeasurements("channelname","",ref Text,herror);

但是我的程序完全停在此行而没有抛出任何异常,我在输出窗口中看到的只是以下消息:

Critical error detected c0000374
Critical error detected c0000374
The program '[4964] ProjectX.exe: Managed' has exited with code 0 (0x0).
The program '[4964] ProjectX.exe: Native' has exited with code 0 (0x0).

我的猜测是,问题在于LPCTSTR的编组类型。

有谁能告诉我我做错了什么或者指出了正确的方向?

提前致谢。

2 个答案:

答案 0 :(得分:1)

据我所知,你所提供的参数1,2和4应该很好。问题可能是参数3。

错误c0000374是堆损坏。这适合。

尝试解决问题的问题是要知道第3个参数的作用。它被声明为一种char**,并且作为[out]参数,我希望它输出为char*。换句话说,我希望函数实际输出一个指针,而不是一个字符串,期望调用者将接收该指针并从中复制一个(以null结尾的)字符串。

您可以通过将入口点重新定义为int *或int **并传入intptr来调查此类调用。这样你应该(a)修复崩溃和(b)看到输出值(作为int或指针)。您可能必须为此进行自己的编组。给定指向COM BSTR的指针,您可以轻松检索所需的值。

但是,根据我对Interop规范的解读,这应该可以正确使用out string sValues而不是ref的声明。调用函数时会发生堆损坏,而不是在它返回时发生。

如果技术性很强,这很有用:http://msdn.microsoft.com/en-us/magazine/cc164193.aspx

我建议你先尝试一下。如果没有,可以尝试调试路由以查看您获得的指针。

答案 1 :(得分:0)

正如@jester注意到LPCTSTR* Values听起来更像是一个字符串数组。您可以尝试将第三个参数更改为字符串数组吗?

public static unsafe extern CoStatus GetCrashMeasurements(string sChannel, string sMeasurements, string[] sValues, IntPtr hError);

并按如下方式调用

GetCrashMeasurements("channelname","",new[] { Text },herror);

您也可以在MarshalAs上指定sValues

public static unsafe extern CoStatus GetCrashMeasurements(string sChannel,
                                                          string sMeasurements,
                                                          [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPTStr)]
                                                          string[] sValues,
                                                          IntPtr hError);