include headers to OpenCL .cl file - c++

I've written an OpenCL kernel in a .cl file. It attempts to #include several headers.
Its compilation fails, since the included header files are "not found".
I am aware that clBuildProgram can take the -I dir option, which adds the directory dir to the list of directories to be searched for the header files.
In the khronus site forum this post http://www.khronos.org/message_boards/viewtopic.php?f=37&t=2535 talks about the issue.
They propose to use clCreateProgramWithSource which specifies all sources (including .h files).
I have a questions regarding this issue:
Which option is better? (clBuildProgram vs. clCreateProgramWithSource, as described above)
If I use clCreateProgramWithSource how does the compiler know what to include? I mean, which source stands for which included file name?
If I use clBuildProgram and there are several directories with include files, how do I specify them?

OpenCL requires you use clCreateProgramWithSource() followed by clBuildProgram().
ClCreateProgramWithSource() creates and returns a cl_program object.
That cl_program object is input into clBuildProgram().
clBuildProgram() allows you to specify compiler options which include the include file
directories. In your case, for header file includes, it will be something like the string:
-I myincludedir1 -I myincludedir2 ...
The compiler used is the internal OpenCL compiler in the OpenCL SDK you are using. So if you
are using AMD's SDK, the AMD OpenCL compiler that is part of their OpenCL SDK will be used. Likewise for Nvidia or Intel.
Its important to check the OpenCL status code for ALL OpenCL function calls.
This is mandatory for clCreateProgramWithSource() and clBuildProrgam() to get
any compiler errors or messages. There is a whole other bit code to write
to get the size of the messages and then retrieve the messages themselves.

The Nvidia OpenCL device drivers have a bug when using -I with a certain number of includes and code length. AMD and Intel don't have this problem. My solutions is to instead concatenate all the .cl files into one large one at runtime. The disadvantage of this is that in debugging code the line number of the error corresponds to the concatentated .cl file and not in the individual .cl files.
I doubt Nvidia will ever fix this. They don't care about OpenCL much anymore.

There is one more dirty trick: you should emulate include yourself (i. e. something like manual amalgamation). It is not very clear for coding, but it works if your OpenCL compiler doesn't support (or supports incorrectly) -I directives. This approach is not perfect (for example, you lose syntax highlighting), but can help for old or buggy OpenCL compilers.
Small simple example of this possibility:
std::string load_file(const std::string &file_name, int max_size = 0x100000)
{
FILE *fp = fopen(file_name.c_str(), "rb");
if (!fp)
{
// print some error or throw exception here
return std::string();
}
char *source = new char[max_size];
size_t source_size = fread(source, 1, max_size, fp);
fclose(fp);
if (!source_size)
{
delete[] source;
// print some error or throw exception here
return std::string();
}
std::string result(source);
delete[] source;
return result;
}
// errors checks are omitted for simplification
std::string full_source = load_file("header.h");
full_source += load_file("source.cl");
const char *source_ptr = full_source.c_str();
size_t source_size = full_source.size();
cl_int_status = CL_SUCCESS;
cl_program program = clCreateProgramWithSource(context, 1,
(const char **)&source_ptr, (const size_t *)&source_size, &ret);
// check status for CL_SUCCESS here
// now you have your program (include + source)

Related

Extracting file from zip using wide string file path in C++

How can you read a file from a zip by opening the zip with a wide string file path? I only saw libraries and code examples with std::string or const char * file paths but I suppose they may fail on Windows with non-ASCII characters. I found this but I'm not using gzip.
Attempts
minizip:
const auto zip_file = unzOpen(jar_file_path.string().c_str()); // No wide string support
if (zip_file == nullptr)
{
throw std::runtime_error("unzOpen() failed");
}
libzippp:
libzippp::ZipArchive zip_archive(jar_file_path.string()); // No wide string support
const auto file_opened_successfully = zip_archive.open(libzippp::ZipArchive::ReadOnly);
if (!file_opened_successfully)
{
throw std::runtime_error("Failed to open the archive file");
}
Zipper does not seem to support wide strings either. Is there any way it can currently be done?
You might be in luck with minizip. I haven't tested this, but I found the following code in mz_strm_os_win32.c:
int32_t mz_stream_os_open(void *stream, const char *path, int32_t mode) {
...
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
if (path_wide == NULL)
return MZ_PARAM_ERROR;
#ifdef MZ_WINRT_API
win32->handle = CreateFile2(path_wide, desired_access, share_mode,
creation_disposition, NULL);
#else
win32->handle = CreateFileW(path_wide, desired_access, share_mode, NULL,
creation_disposition, flags_attribs, NULL);
#endif
mz_os_unicode_string_delete(&path_wide);
...
So it looks very much as if the author catered explicitly for Windows' lack of built-in UTF-8 support for the 'narrow string' file IO functions. It's worth a try at least, let's just hope that that function actually gets called when you try to open a zip file.
Regarding Minizip library, API function unzOpen() works well with UTF-8 only on Unix systems, but on Windows, path will be processed only in the current CodePage. For get full Unicode support, need to use new API functions unzOpen2_64() and zipOpen2_64() that allows to pass structure with set of functions for work with file system. Please see my answer with details in the similar question.

Is there a format processor to write my own printf-like function and keep the %d style arguments, without using sprintf?

I'm writing a serial interface for an MCU, and I want to know how one would create a printf-like function to write to the serial UART. I can write to the UART, but to save memory and stack space, and avoid temp string buffers, I would prefer to do that write directly instead of doing sprintf() to a string and then writing the string via serial. There is no kernel and no file handling, so FILE* writes like those from fprintf() won't work (but sprintf() does).
Is there something that processes formatted strings for each char, so I can print char-by-char as it parses the format string, and applies the related arguments?
We are using newlib as part of the efm32-base project.
UPDATE
I would like to note that ultimately we implemented the _write() function because thats all newlib needs to light up printf.
Standard C printf family of functions don't have a "print to a character callback" type of functionality. Most embedded platforms don't support fprintf either.
First try digging around the C runtime for your platform, it might have a built-in solution. For example, ESP-IDF has ets_install_putc1() which essentially installs a callback for printf (though its ets_printf already prints to UART0).
Failing that, there are alternative printf implementations designed specifically for embedded applications which you can adapt to your needs.
For example mpaland/printf has a function taking the character printer callback as the first argument:
int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...);
Also see this related question: Minimal implementation of sprintf or printf.
You had said [in your top comments] that you had GNU, so fopencookie for the hooks [I've used it before with success].
Attaching to stdout may be tricky, but doable.
Note that we have: FILE *stdout; (i.e. it's [just] a pointer). So, simply setting it to the [newly] opened stream should work.
So, I think you can do, either (1):
FILE *saved_stdout = stdout;
Or (2):
fclose(stdout);
Then, (3):
FILE *fc = fopencookie(...);
setlinebuf(fc); // and whatever else ...
stdout = fc;
You can [probably] adjust the order to suit (e.g. doing fclose first, etc.)
I had looked for something analogous to freopen or fdopen to fit your situation, but I didn't find anything, so doing stdout = ...; may be the option.
This works fine if you do not have any code that tries to write to fd 1 directly (e.g. write(1,"hello\n",6);).
Even in that case, there is probably a way.
UPDATE:
Do you know if FILE*stdout is a const? If so, I might need to do something crazy like FILE **p = &stdout and then *p = fopencookie(...)
You were right to be concerned, but not for quite the reason you think. Read on ...
stdout is writable but ...
Before I posted, I checked stdio.h, and it has:
extern FILE *stdout; /* Standard output stream. */
If you think about it, stdout must be writable.
Otherwise, we could never do:
fprintf(stdout,"hello world\n");
fflush(stdout);
Also, if we did a fork, then [in the child] if we wanted to set up stdout to go to a logfile, we'd need to be able to do:
freopen("child_logfile","w",stdout);
So, no worries ...
Trust but verify ...
Did I say "no worries"? I may have been premature ;-)
There is an issue.
Here is a sample test program:
#define _GNU_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#if 1 || DEBUG
#define dbgprt(_fmt...) \
do { \
fprintf(stderr,_fmt); \
fflush(stderr); \
} while (0)
#else
#define dbgprt(_fmt...) \
do { } while (0)
#endif
typedef struct {
int ioport;
} uartio_t;
char *arg = "argument";
ssize_t
my_write(void *cookie,const char *buf,size_t len)
{
uartio_t *uart = cookie;
ssize_t err;
dbgprt("my_write: ENTER ioport=%d buf=%p len=%zu\n",
uart->ioport,buf,len);
err = write(uart->ioport,buf,len);
dbgprt("my_write: EXIT err=%zd\n",err);
return err;
}
int
my_close(void *cookie)
{
uartio_t *uart = cookie;
dbgprt("my_close: ioport=%d\n",uart->ioport);
int err = close(uart->ioport);
uart->ioport = -1;
return err;
}
int
main(void)
{
cookie_io_functions_t cookie = {
.write = my_write,
.close = my_close
};
uartio_t uart;
printf("hello\n");
fflush(stdout);
uart.ioport = open("uart",O_WRONLY | O_TRUNC | O_CREAT,0644);
FILE *fc = fopencookie(&uart,"w",cookie);
FILE *saved_stdout = stdout;
stdout = fc;
printf("uart simple printf\n");
fprintf(stdout,"uart fprintf\n");
printf("uart printf with %s\n",arg);
fclose(fc);
stdout = saved_stdout;
printf("world\n");
return 0;
}
Program output:
After compiling, running with:
./uart >out 2>err
This should produce an expected result. But, we get (from head -100 out err uart):
==> out <==
hello
uart simple printf
world
==> err <==
my_write: ENTER ioport=3 buf=0xa90390 len=39
my_write: EXIT err=39
my_close: ioport=3
==> uart <==
uart fprintf
uart printf with argument
Whoa! What happened? The out file should just be:
hello
world
And, the uart file should have three lines instead of two:
uart printf
uart simple printf
uart printf with argument
But, the uart simple printf line went to out instead of [the intended] uart file.
Again, whoa!, what happened?!?!
Explanation:
The program was compiled with gcc. Recompiling with clang produces the desired results!
It turns out that gcc was trying to be too helpful. When compiling, it converted:
printf("uart simple printf\n");
Into:
puts("uart simple printf");
We see that if we disassemble the executable [or compile with -S and look at the .s file].
The puts function [apparently] bypasses stdout and uses glibc's internal version: _IO_stdout.
It appears that glibc's puts is a weak alias to _IO_puts and that uses _IO_stdout.
The _IO_* symbols are not directly accessible. They're what glibc calls "hidden" symbols--available only to glibc.so itself.
The real fix:
I discovered this after considerable hacking around. Those attempts/fixes are in an appendix below.
It turns out that glibc defines (e.g.) stdout as:
FILE *stdout = (FILE *) &_IO_2_1_stdout_;
Internally, glibc uses that internal name. So, if we change what stdout points to, it breaks that association.
In actual fact, only _IO_stdout is hidden. The versioned symbol is global but we have to know the name either from readelf output or by using some __GLIBC_* macros (i.e. a bit messy).
So, we need to modify the save/restore code to not change the value in stdout but memcpy to/from what stdout points to.
So, in a way, you were correct. It is [effectively] const [readonly].
So, for the above sample/test program, when we want to set a new stdout, we want:
FILE *fc = fopencookie(...);
FILE saved_stdout = *stdout;
*stdout = *fc;
When we want to restore the original:
*fc = *stdout;
fclose(fc);
*stdout = saved_stdout;
So, it really wasn't gcc that was the issue. The original save/restore we developed was incorrect. But, it was latent. Only when gcc called puts did the bug manifest itself.
Personal note: Aha! Now that I got this code working, it seems oddly familiar. I'm having a deja vu experience. I'm pretty sure that I've had to do the same in the past. But, it was so long ago, that I had completely forgotten about it.
Workarounds / fixes that semi-worked but are more complex:
Note: As mentioned, these workarounds are only to show what I tried before finding the simple fix above.
One workaround is to disable gcc's conversion from printf to puts.
The simplest way may be to [as mentioned] compile with clang. But, some web pages say that clang does the same thing as gcc. It does not do the puts optimization on my version of clang [for x86_64]: 7.0.1 -- YMMV
For gcc ...
A simple way is to compile with -fno-builtins. This fixes the printf->puts issue but disables [desirable] optimizations for memcpy, etc. It's also undocumented [AFAICT]
Another way is to force our own version of puts that calls fputs/fputc. We'd put that in (e.g.) puts.c and build and link against it:
#include <stdio.h>
int
puts(const char *str)
{
fputs(str,stdout);
fputc('\n',stdout);
}
When we just did: stdout = fc; we were deceiving glibc a bit [actually, glibc was deceiving us a bit] and that has now come back to haunt us.
The "clean" way would be to do freopen. But, AFAICT, there is no analogous function that works on a cookie stream. There may be one, but I haven't found it.
So, one of the "dirty" methods may be the only way. I think using the "custom" puts function method above would be the best bet.
Edit: It was after I reread the above "deceiving" sentence that I hit on the simple solution (i.e. It made me dig deeper into glibc source).
depending on your standard library implementation you need to write your own versions of fputc or _write functions.

How to properly navigate directory paths in C++

I'm working on a solution within Visual Studio. It currently has two projects.
I will represent Directories or folders with capitals letters, and filenames will be all lower case. My solution structure is as follows:
SolutionDir
ProjectLib
source files
Shaders
shader files
ProjectApp
source files
x64
Debug
app.exe // debug build
Release
app.exe // release build
Within ProjectLib I have a function to open and read my Shader files. Here is what my function looks like:
std::vector<char> VRXShader::readFile(std::string_view shadername) {
std::string filename = std::string("Shaders/");
filename.append(shadername);
std::ifstream file(filename.data(), std::ios::ate | std::ios::binary);
if (!file.is_open()) {
throw std::runtime_error("failed to open file!");
}
size_t fileSize = static_cast<size_t>(file.tellg());
std::vector<char> buffer(fileSize);
file.seekg(0);
file.read(buffer.data(), fileSize);
file.close();
return buffer;
}
This function is being called within my VRXDevices::createPipeline function and here is the relevant code:
void VRXDevices::createPipeline(
VkDevice device, VkExtent2D swapChainExtent, VkRenderPass renderPass,
const std::vector<std::string_view>& shaderNames,
VkPipelineLayout& pipelineLayout, VkPipeline& pipeline
) {
std::vector<std::vector<char>> shaderCodes;
shaderCodes.resize(shaderNames.size());
for (auto& name : shaderNames) {
auto shaderCode = VRXShader::readFile(name.data());
}
// .... more code
}
The names are being created and passed to this function from my VRXEngine::initVulkan function which can be seen here:
void VRXEngine::initVulkan(
std::string_view app_name, std::string_view engine_name,
glm::ivec3 app_version, glm::ivec3 engine_version
) {
//... code
std::vector<std::string_view> shaderFilenames{ "vert.spv", "frag.spv" };
VRXDevices::createPipeline(device_, swapChainExtent_, renderPass_, shaderFilenames, pipelineLayout_, graphicsPipeline_);
}
I'm using just the name of the shader files such as vert.spv, frag.spv, geom.spv etc. I'm not including the paths here because these will be used as the key to a std::map<string_view, object>. So I'm passing a vector of these names from my ::initVulkan function into ::createPipeline().
Within ::createPipeline() is where ::readFile() is being called passing in the string_view.
Now as for my question... within ::readFile() I'm creating a local string and trying to initialize it with the appropriate path... then append to it the string_view for the shader's filename as can be seen from these two lines...
std::string filename = std::string("Shaders/");
filename.append(shadername);
I'm trying to figure out the appropriate string to initialize filename with... Shaders/ will be a part of the name, but it's not finding the file and I'm not sure what the appropriate prefix should be...
My working directories within both projects are as follows:
ProjectApp -> $(SolutionDir)x64/Release AND $(SolutionDir)x64/Debug
ProjectLib -> $(SolutionDir)x64/Release AND $(SolutionDir)x64/Debug
So I need to go back 2 directories then into VRX Engine/Shader...
What is the correct string value for navigating back directories?
Would I initialize filename with "../../VRX Engine/Shaders/" or is it "././" also, should I have quotes around VRX Engine since there is a space in the folder name? What do I need to initialize filename with before I append the shader name to it?
How to properly navigate directory paths in C++
It depends on which C++ standard your implementation claims to be compliant with.
Or else which additional libraries can you use.
C++ is useful on computers without directories (e.g. inside some operating system kernel coded in C++ and compiled with GCC, see OSDEV for examples).
Look on en.cppreference.com for details.
Licensing constraints could matter when using extra open source libraries.
If your implementation is C++17 compliant (in a "hosted" not "freestanding" way), use the std::filesystem part of the standard library.
If your operating system supports the Qt or POCO frameworks and you are allowed to use them (e.g. on C++11), you could use appropriate APIs. So QDir and related classes with Qt, Poco::Path and related classes with POCO.
Perhaps you want to code just for the WinAPI. Then read its documentation (I never coded on Windows myself, just on POSIX or Unix -e.g. Linux- and MSDOS....).
I was originally initializing my local temp string properly with "../../VRX Engine/Shaders/" before appending the string_view to it to be able to open the file. This was actually correct, but because it didn't initially work, I was assuming that it was wrong.
The correct string value for going back one directory should be "../" at least on Windows, I'm not sure about Linux, Mac, Android, etc...
My problem wasn't with the string at all, it pertained to settings within my projects. Within my project that builds into an executable, I had its working directory set to $(SolutionDir)x64/Debug and $(SolutionDir)x64/Release respectively which is correct for my solutions structure.
The issue was within my Engine project that is being built as a static library. Within its settings for its working directory, I had forgotten to modify both of the Debug and Release build options... These were still set to the default values of Visual Studio which I believe is (ProjectDir). Once I changed these to $(SolutionDir)x64/Debug and $(SolutionDir)x64/Release to match that of my ApplicationProject, I was able to open and read the contents of the files.

C++/C Virtual/Embeddable File System [Cross Compatible (Library)]?

I want to experiment with some Virtual File Systems, like having 1 file in which all data is stored (1 file = virtual disk). For example I can open the virtual disk and put files into it, write data to the files, read data from file, open files and use fseek etc..
Is there any library I can use for that? License stuff etc is not important. I just want to test it on my machine because I'm borred, So I want to try this in C++/C.
Thanks in advance! :)
If the library is windows only then it's also okay, maybe I will find a linux library so I can make 2 projects?
Edit:
Thanks to BRPocock I know my question is a bit unclear. What I really want is a library which has the ability to store files, read files, and perform file operations on a VFS which the library already provides. And ofcourse mounting. So, What I would preffer is if there is a library which gives me this functions in C++:
OpenVirtualDrive(const name[]);//
CloseVirtualDrive(handle);//
fopen(const name[], mode);//open file, return handle
fclose(handle);//close handle
ftemp(); //open file as temporary file
fremove(const name[]);//delete file
fwrite(handle, array[]);//write array to file
fread(handle, array[], size = sizeof array, pack = false);//read from file
fputchar(handle, value, utf8 = true);//put char into file
fgetchar(handle, value, utf8 = true);//read char from file, move pointer
fblockwrite(handle, const buffer[], size = sizeof buffer);//write block
fblockread(handle, buffer[], size = sizeof buffer);//read block, move pointer
fseek(handle, position = 0, seek_whence: whence = seek_start);//move pointer
flength(handle);//size of file
fexist(const pattern[]);//check if file exists
fmatch(name[], const pattern[], index = 0, size = sizeof name);//search for file
This is just pseudo code :P
Linux (and many BSDs, including, I believe, MacOSX) uses the FUSE system (http://fuse.sourceforge.net/) to provide those kinds of services. You should be able to find many examples on the 'Net.
I believe the “accepted” way to do the same thing on Windows is to write it as a device-driver loadable module (.dll) … a quick Googling points at http://msdn.microsoft.com/en-us/windows/hardware/gg463062 as the starting-point, perhaps.
Our SolFS will do the job. Evaluation license will be ok for you and we offer free licenses for non-commercial public projects as well. If you want a filesystem visible from other applications, you need OS edition of SolFS, and if you are going to call its functions only from your application, then SolFS Application Edition is enough.

How to embed a file into an executable file?

I have two problems, the first has been solved.
Current problem
If I embed a file that requires a library to load it, such as a jpeg image or a mp3 music, I will need to use the file as input to the library. However, each library is different and uses a way to get a file as input, the input may be the file name or a FILE* pointer (from libc's file interface).
I would like to know how to access an embedded file with a name. It will be inefficient if I create a temporary file, is there another way? Can I map a file name to memory? My platforms are Windows and Linux.
If show_file(const char* name) is a function from a library, I will need a string to open the file.
I have seen these questions:
How to get file descriptor of buffer in memory?
Getting Filename from file descriptor in C
and the following code is my solution. Is it a good solution? Is it inefficient?
# include <stdio.h>
# include <unistd.h>
extern char _binary_data_txt_start;
extern const void* _binary_data_txt_size;
const size_t len = (size_t)&_binary_data_txt_size;
void show_file(const char* name){
FILE* file = fopen(name, "r");
if (file == NULL){
printf("Error (show_file): %s\n", name);
return;
}
while (true){
char ch = fgetc(file);
if (feof(file) )
break;
putchar( ch );
}
printf("\n");
fclose(file);
}
int main(){
int fpipe[2];
pipe(fpipe);
if( !fork() ){
for( int buffsize = len, done = 0; buffsize>done; ){
done += write( fpipe[1], &_binary_data_txt_start + done, buffsize-done );
}
_exit(0);
}
close(fpipe[1]);
char name[200];
sprintf(name, "/proc/self/fd/%d", fpipe[0] );
show_file(name);
close(fpipe[0]);
}
The other problem (solved)
I tried to embed a file on Linux, with GCC, and it worked. However, I tried to do the same thing on Windows, with Mingw, and it did not compile.
The code is:
# include <stdio.h>
extern char _binary_data_txt_start;
extern char _binary_data_txt_end;
int main(){
for (char* my_file = &_binary_data_txt_start; my_file <= &_binary_data_txt_end; my_file++)
putchar(*my_file);
printf("\n");
}
The compilation commands are:
objcopy --input-target binary --output-target elf32-i386 --binary-architecture i386 data.txt data.o
g++ main.cpp data.o -o test.exe
On Windows, I get the following compiler error:
undefined reference to `_binary_data_txt_start'
undefined reference to `_binary_data_txt_end'
I tried to replace elf32-i386 with i386-pc-mingw32, but I still get the same error.
I think that for this to work with MinGW you'll need to remove the leading underscore from the names in the .c file. See Embedding binary blobs using gcc mingw for some details.
See if using the following helps:
extern char binary_data_txt_start;
extern char binary_data_txt_end;
If you need the same source to work for Linux or MinGW builds, you might need to use the preprocessor to have the right name used in the different environments.
If you're using a library that requires a FILE* for reading data, then you can use fmemopen(3) to create a pseudofile out of a memory blob. This will avoid creating a temporary file on disk. Unfortunately, it's a GNU extension, so I don't know if it's available with MinGW (likely not).
However, most well-written libraries (such as libpng and the IJG's JPEG library) provide routines for opening a file from memory as opposed to from disk. libpng, in particular, even offers a streaming interface, where you can incrementally decode a PNG file before it's been completely read into memory. This is useful if, say, you're streaming an interlaced PNG from the network and you want to display the interlaced data as it loads for a better user experience.
On Windows, you can embed custom resource into executable file. You would need a .RC file and a resource compiler. With Visual Studio IDE you can do it without hassle.
In your code, you would use FindResource, LoadResource and LockResource functions to load the contents into memory at runtime. A sample code that reads the resource as long string:
void GetResourceAsString(int nResourceID, CStringA &strResourceString)
{
HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(nResourceID), L"DATA");
HGLOBAL hResHandle = LoadResource(NULL, hResource);
const char* lpData = static_cast<char*> ( LockResource(hResHandle) );
strResourceString.SetString(lpData, SizeofResource(NULL, hResource));
FreeResource(hResource);
}
Where nResourceID is the ID of resource under custom resource type DATA. DATA is just a name, you may choose another name. Other in-built resources are cursors, dialogs, string-tables etc.
I've created a small library called elfdataembed which provides a simple interface for extracting/referencing sections embedded using objcopy. This allows you to pass the offset/size to another tool, or reference it directly from the runtime using file descriptors. Hopefully this will help someone in the future.
It's worth mentioning this approach is more efficient than compiling to a symbol, as it allows external tools to reference the data without needing to be extracted, and it also doesn't require the entire binary to be loaded into memory in order to extract/reference it.
Use nm data.o to see what it named the symbols. It may be something as simple as the filesystem differences causing the filename-derived symbols to be different (eg filename capitalized).
Edit: Just saw your second question. If you are using threads you can make a pipe and pass that to the library (first using fdopen() if it wants a FILE *). If you are more specific about the API you need to talk to I can add more specific advice.