Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I pass FILE object across DLLs boundaries?

I have a C++ framework where some calculations are delegated to (sometimes auto generated) C functions or C++ functions with external "C" linkage. These are low-level routines that must be evaluated very fast and with minimal overhead and they typically reside in separate shared objects/DLLs. Their current signature is something along the lines of:

int my_generated_function(const double* input, double* output, double* work);

which will reside in a shared library loaded using dlopen on POSIX or LoadLibrary on Windows. The corresponding function pointers are extracted using dlsym(handle, "my_generated_function") on POSIX or GetProcAddress(handle, TEXT("my_generated_function")) on Windows.

Is it safe and portable to augment the signature with a FILE object pointer?

int my_generated_function(const double* input, double* output, double* work,
                          FILE* logfile);

Note that the shared object containing my_generated_function might have been compiled with a different (but binary compatible) compiler than the code that loads the shared object.

like image 868
Joel Avatar asked Sep 06 '17 14:09

Joel


1 Answers

You can think of the FILE* as an opaque handle. The problem is that the actual object under this handle, in other words, the definition of the FILE structure, and its implementation details, are compiler/CRT specific.

So, to my knowledge, there's no guarantee that the FILE implementation of e.g. Visual Studio 2008 or 2010 is the same of the ones that come in VS2015 or 2017. In other words, even if the name of the structure (FILE) is the same, the implementation details may very well change from one version of the CRT to another.

So, I'd suggest to not have a FILE* at the DLL boundaries, unless you want to constrain your clients to use the same version of the VC++ compiler/CRT.

On the other hand, if you need a cross-compiler/CRT compatible handle at the DLL interface boundary, I'd suggest using the Win32 HANDLE type (the one that is returned from APIs like CreateFile). This is defined at the OS level, so it's independent from the particular VC++ compiler/CRT.

If you want to get the Win32 HANDLE from a FILE*, you can use _get_osfhandle with _fileno, as explained in this SO answer.

like image 153
Mr.C64 Avatar answered Sep 30 '22 00:09

Mr.C64