我可以跨 DLL 边界传递 FILE 对象吗?
Can I pass FILE object across DLLs boundaries?
我有一个 C++ 框架,其中一些计算委托给(有时是自动生成的)C 函数或具有外部 "C" 链接的 C++ 函数。这些是低级例程,必须以非常快的速度和最小的开销进行评估,它们通常驻留在单独的共享 objects/DLLs 中。他们目前的签名是这样的:
int my_generated_function(const double* input, double* output, double* work);
将驻留在使用 POSIX 上的 dlopen
或 Windows 上的 LoadLibrary
加载的共享库中。使用POSIX上的dlsym(handle, "my_generated_function")
或Windows上的GetProcAddress(handle, TEXT("my_generated_function"))
提取相应的函数指针。
使用 FILE 对象指针扩充签名是否安全且可移植?
int my_generated_function(const double* input, double* output, double* work,
FILE* logfile);
请注意,包含 my_generated_function
的共享对象可能是使用与加载共享对象的代码不同(但二进制兼容)的编译器编译的。
您可以将 FILE*
视为不透明句柄。问题是这个句柄下的实际对象,换句话说,FILE 结构的定义及其实现细节,是 compiler/CRT 具体的。
因此,据我所知,不能保证 FILE 实现例如Visual Studio2008或2010与VS2015或2017中的相同。换句话说,即使结构(FILE)的名称相同,实施细节很可能会从 CRT 的一个版本更改为另一个版本。
所以,我建议 不要 在 DLL 边界有一个 FILE*
,除非你想限制你的客户使用 版本的 VC++ compiler/CRT.
另一方面,如果您在 DLL 接口边界需要一个跨 compiler/CRT 兼容句柄,我建议使用 Win32 HANDLE
类型(从 API 返回的类型)像 CreateFile
)。这是在 OS 级别定义的,因此它独立于特定的 VC++ compiler/CRT.
如果您想从 FILE*
获取 Win32 HANDLE
,您可以使用 _get_osfhandle
和 _fileno
,如 this SO answer 中所述。
我有一个 C++ 框架,其中一些计算委托给(有时是自动生成的)C 函数或具有外部 "C" 链接的 C++ 函数。这些是低级例程,必须以非常快的速度和最小的开销进行评估,它们通常驻留在单独的共享 objects/DLLs 中。他们目前的签名是这样的:
int my_generated_function(const double* input, double* output, double* work);
将驻留在使用 POSIX 上的 dlopen
或 Windows 上的 LoadLibrary
加载的共享库中。使用POSIX上的dlsym(handle, "my_generated_function")
或Windows上的GetProcAddress(handle, TEXT("my_generated_function"))
提取相应的函数指针。
使用 FILE 对象指针扩充签名是否安全且可移植?
int my_generated_function(const double* input, double* output, double* work,
FILE* logfile);
请注意,包含 my_generated_function
的共享对象可能是使用与加载共享对象的代码不同(但二进制兼容)的编译器编译的。
您可以将 FILE*
视为不透明句柄。问题是这个句柄下的实际对象,换句话说,FILE 结构的定义及其实现细节,是 compiler/CRT 具体的。
因此,据我所知,不能保证 FILE 实现例如Visual Studio2008或2010与VS2015或2017中的相同。换句话说,即使结构(FILE)的名称相同,实施细节很可能会从 CRT 的一个版本更改为另一个版本。
所以,我建议 不要 在 DLL 边界有一个 FILE*
,除非你想限制你的客户使用 版本的 VC++ compiler/CRT.
另一方面,如果您在 DLL 接口边界需要一个跨 compiler/CRT 兼容句柄,我建议使用 Win32 HANDLE
类型(从 API 返回的类型)像 CreateFile
)。这是在 OS 级别定义的,因此它独立于特定的 VC++ compiler/CRT.
如果您想从 FILE*
获取 Win32 HANDLE
,您可以使用 _get_osfhandle
和 _fileno
,如 this SO answer 中所述。