Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当Delphi类型为“时,我使用什么C”参数类型;出PChar”吗;?_C#_Interface_Com Interop_Delphi - Fatal编程技术网

C# 当Delphi类型为“时,我使用什么C”参数类型;出PChar”吗;?

C# 当Delphi类型为“时,我使用什么C”参数类型;出PChar”吗;?,c#,interface,com-interop,delphi,C#,Interface,Com Interop,Delphi,我无法将下面的接口定义从Delphi转换为C#: 我已通过以下方式尝试使用StringBuilder: [ComVisible(true), ComImport, SuppressUnmanagedCodeSecurity, Guid("BD78EF46-1809-11D6-A458-EDAE78F1DF12"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDCDSPFilterInterface

我无法将下面的接口定义从Delphi转换为C#:

我已通过以下方式尝试使用StringBuilder:

[ComVisible(true), ComImport, SuppressUnmanagedCodeSecurity,
Guid("BD78EF46-1809-11D6-A458-EDAE78F1DF12"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDCDSPFilterInterface : IBaseFilter
{
    [PreserveSig]
    int get_FilterName(int Index, [MarshalAs(UnmanagedType.LPStr)] StringBuilder Name);
}
我尝试了LPStr、LPWStr,它们都在字符串生成器中提供垃圾字符,LPTStr失败,并显示一条错误消息,表明不允许这种编组组合

德里的方法定义为:

function TDCDSPFilter.get_FilterName(Index : integer; out Name : PChar): HRESULT; stdcall;
begin
{$IFDEF EXCEPT_DEBUG}try{$ENDIF}
  FcsFilter.Lock;
  try
  {$IFDEF WITH_INTERNAL_DSP}
    Result := S_FALSE;
    if (Index < 0) or (Index > fFilters.Count -1) then Exit;
    Name := PChar(fFilters.Name[Index]);
    Result := S_OK;
  {$ELSE}
    Result := E_NOTIMPL;
  {$ENDIF}
  finally
    FcsFilter.UnLock;
  end;
{$IFDEF EXCEPT_DEBUG} except er('TDCDSPFilter.get_FilterName'); end; {$ENDIF}
end;
我的所有其他接口方法都能很好地与其他基本类型(in和ref)配合使用,除了这个带有PChar输出的方法

我得到S_OK,但StringBuilder中的字符串是垃圾

我知道该方法是正确调用的,因为如果我传递了错误的索引,我会得到S_FALSE(正如方法体所定义的那样)

有谁能帮助为Delphi out PChar提供正确的编组吗?

尝试使用for
Name
参数,然后使用获取字符串的内容

参考资料:


那是一个设计相当糟糕的界面。这是一个COM接口,因此它应该使用COM字符串,
BSTR

但是,目前,C端必须将
PChar
封送为类型为
IntPtr
的out参数。宣言应当是:

[PreserveSig]
uint get_FilterName(int Index, out IntPtr Name);
然后,根据字符串的编码,可以通过调用
Marshal.PtrToStringAnsi
Marshal.PtrToStringUni
来恢复字符串

您不能使用
StringBuilder
,因为这适用于调用者分配缓冲区的情况。这在这里是不会发生的

正如我所说,使用COM字符串会更好。代码如下所示:

Delphi

function TDCDSPFilter.get_FilterName(Index: integer; 
    out Name : WideString): HRESULT; stdcall;
C#


当然,这假设您可以修改接口。很可能你不能。在这种情况下,您只能使用
out IntPtr

尝试使用IntPtr,然后Marshal.PtrToStringAnsi。“int-get_-FilterName(int-Index,out-IntPtr-Name);”是互操作,PtrToStringAnsi给出了我所希望的:)请将其作为答案写下来。感谢提供详细信息!正如你所说,我不能修改界面,因为它是我在direct show中使用的过滤器的一部分。但是谢谢你的解释。
[PreserveSig]
uint get_FilterName(int Index, out IntPtr Name);
function TDCDSPFilter.get_FilterName(Index: integer; 
    out Name : WideString): HRESULT; stdcall;
[PreserveSig]
uint get_FilterName(
    int Index,
    [MarshalAs(UnmanagedType.BStr)]
    out string Name
);