Win32 API waveInGetErrorText 声明到 C#

Win32 API waveInGetErrorText declaration into C#

需要打电话

MMRESULT waveInGetErrorText(
   MMRESULT mmrError,
   LPTSTR   pszText,
   UINT     cchText
);

来自 C# 代码。未在 PINVOKE.net 找到声明。 函数的描述是 here

MMRESULT 只是一个 uint 值。 0 - 没有错误..任何其他不超过 20 的值 - 都是错误。

尝试了很多模式。总是返回一个空字符串。

[DllImport("Winmm", EntryPoint = "waveInGetErrorText")]
public static extern uint waveInGetErrorText(uint mmrError, IntPtr pszText, uint cchText);

调用时

uint r = 12 // for example return value is 12
uint szErrorMessage = 128;
string errorMessage = new string(' ', (int) szErrorMessage);
IntPtr strPtr = Marshal.StringToBSTR(errorMessage);

r = waveInGetErrorText(r, strPtr, szErrorMessage);

return字符串总是空的,保留128字节的空格。 尝试了 refout 没有成功..

请问,知道为什么吗?

您的定义:

public static extern uint waveInGetErrorText(uint mmrError, 
                                             IntPtr pszText, 
                                             uint cchText);

...不足以告诉 .NET IntPtr pszText 正在输出任何内容。默认情况下,编译器用 [in] marshal 属性修饰所有参数。所以你上面的定义等同于:

public static extern uint waveInGetErrorText([in] uint mmrError, 
                                             [in] IntPtr pszText, 
                                             [in] uint cchText);

现在如果你有这样的定义:

int CountRecords (out int numErrors)

...编译器将其转换为:

int CountRecords ([out] out int numErrors)

...我相信。无论如何,out(任何一种形式)告诉编译器期望从 p-invoke 中得到一些东西。因为您没有指定 out[out],所以调用完成后不会将任何内容传回参数。

现在您可以使用 out string,但 StringBuilder 更容易。 StringBuilder 等某些类型被 .NET 识别为 "hey, for this parameter I expect something in return"out 是可选的。

将您的定义更改为:

[DllImport("Winmm", EntryPoint = "waveInGetErrorText")]
public static extern uint waveInGetErrorText(uint mmrError, StringBuilder text, uint cchText);

我相信你应该这样称呼它:

uint r = 12 // for example return value is 12
StringBuilder data = new StringBuilder(255);
r = waveInGetErrorText(r, data, data.Capacity);

告诉我更多

  • When is it necessary/appropriate to use InAttribute and OutAttribute for COM Interop