簡體   English   中英

C#使用FILE *參數調用C函數

[英]C# call C function with FILE* parameter

我在C庫的結構中定義了以下函數指針:

struct SOME_STRUCT {
    [...]
    uint8_t(*printinfo) (SOME_STRUCT * ss, FILE * hFile);
    [...]
}

此函數將一些數據寫入文件句柄hFile,我想從C#調用它。 在C#我有:

[StructLayout(LayoutKind.Sequential)]
public struct SomeStruct
{
    [...]
    public printinfoDelegate printinfo;

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate byte printinfoDelegate(IntPtr ss, IntPtr hFile);
    [...]
}

我使用以下代碼來調用該函數:

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();
    }
}

但是我無法讓它發揮作用。 我懷疑問題是我不能只將文件流中的句柄作為文件*傳遞。 任何幫助將不勝感激...

.NET中的句柄指的是Win32 HANDLE (或HINSTANCE等等),例如CreateFile函數返回的HANDLE 另一方面, FILE *是C運行時庫的一部分,並通過調用fopen函數返回。

因此,如果你想使用帶有FILE *參數的函數,那么你也必須P / Invoke fopen方法,就像在這里一樣

我相信沒有辦法將FileStream編組為FILE *。 如果只需要C函數內的流,可以通過callind fdopen()創建句柄。

你需要為fopenfclose聲明包裝器。 你需要的是這樣的:

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM