C#使用FILE*参数调用C函数

C#使用FILE*参数调用C函数,c#,c,pinvoke,C#,C,Pinvoke,我在C库的结构中定义了以下函数指针: struct SOME_STRUCT { [...] uint8_t(*printinfo) (SOME_STRUCT * ss, FILE * hFile); [...] } 这个函数将一些数据写入文件句柄hFile,我想从C#调用它。在C#中,我有: 我使用以下代码调用该函数: SomeStruct sStruct = [...]; String output; using (FileStream stream = new F

我在C库的结构中定义了以下函数指针:

struct SOME_STRUCT {
    [...]
    uint8_t(*printinfo) (SOME_STRUCT * ss, FILE * hFile);
    [...]
}
这个函数将一些数据写入文件句柄hFile,我想从C#调用它。在C#中,我有:

我使用以下代码调用该函数:

SomeStruct sStruct = [...];
String output;

using (FileStream stream = new FileStream(tmpFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
    IntPtr structPtr = Marshal.AllocHGlobal(Marshal.SizeOf(sStruct));
    Marshal.StructureToPtr(sStruct, structPtr, false);

    byte result = sStruct.printinfo(structPtr, stream.SafeFileHandle.DangerousGetHandle());

    stream.Seek(0, System.IO.SeekOrigin.Begin);

    using (System.IO.StreamReader reader = new System.IO.StreamReader(stream))
    {
        output = reader.ReadToEnd();
    }
}

但是我不能让它工作。我怀疑问题在于我不能将句柄作为文件*从filestream传递出去。非常感谢您的帮助……

我相信没有办法将文件流封送为文件*。如果您只需要C函数内部的流,则可以通过callind fdopen()创建句柄。

在.NET中的句柄请参考Win32
句柄(或
HINSTANCE
等),例如函数返回的句柄。另一方面,
文件*
是C运行时库的一部分,通过调用
fopen
函数返回


因此,如果您想使用接受
文件*
参数的函数,那么您也必须p/调用
fopen
方法,如中所示。

您需要声明
fopen
fclose
的包装器。你需要的是这样的东西:

public static class LegacyFileManager
{
    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern IntPtr fopen(String filename, String mode);
    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern Int32 fclose(IntPtr file);
}
然后在代码中:

IntPtr fileHandle = LegacyFileManager.fopen(tmpFileName, "r+");

// your logic here

LegacyFileManager.fclose(fileHandle);

文件*不仅仅是句柄。导入另一个C函数,该函数从文件名中为您提供一个文件*(另一个函数用于再次关闭该文件)。您的怀疑是正确的,.net文件流与文件*无关。
IntPtr fileHandle = LegacyFileManager.fopen(tmpFileName, "r+");

// your logic here

LegacyFileManager.fclose(fileHandle);