[英]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()創建句柄。
你需要為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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.