hosseinmoein / DataFrame

C++ DataFrame for statistical, Financial, and ML analysis -- in modern C++ using native types and contiguous memory storage
https://hosseinmoein.github.io/DataFrame/
BSD 3-Clause "New" or "Revised" License
2.46k stars 310 forks source link

DataFrame across shares libraries (windows DLL) #188

Closed TL4903 closed 2 years ago

TL4903 commented 2 years ago

Hi, thanks for this great library, but I'm having a problem passing a reference/pointer to a DataFrame object across a DLL. I know templates need explicit specification before passing to a DLL and that's what I believe is causing the HeteroVector to come up empty on the DLL side while other attributes of the object like the size and index get passed correctly. Do you have any experience on how to get this to work? I know it's possible to serialize the DataFrame back and forth, but I'd like to avoid that overhead if at all possible.

hosseinmoein commented 2 years ago

Unfortunately I am not very familiar with Windows environment (DLL and stuff) development. Also, I am not sure I completely understand your scenario. Maybe if you show some code snippet, it becomes clearer.

TL4903 commented 2 years ago

Sure, here's some code. I can attach the entire Visual Studio solution if that'll help. The DataFrame object is built into a static library and I've added both HMDF_SHARED and DataFrame_EXPORTS as preprocessor definitions. I've also added the same preprocessor definitions to my DLL and exe projects. The DLL links against that static library and uses sample code:

DLL .h

ifdef DATAFRAMEWORKDLL_EXPORTS

define DATAFRAMEWORKDLL_API __declspec(dllexport)

else

define DATAFRAMEWORKDLL_API __declspec(dllimport)

endif

extern "C" DATAFRAMEWORKDLL_API BOOL __cdecl Work(ULDataFrame& df);

DLL .cpp

DATAFRAMEWORKDLL_API BOOL __cdecl Work(ULDataFrame& df) { df.write<std::ostream, double>(std::cout, io_format::csv2);

return TRUE; }

My exec just creates a simple DataFrame and passes it to the DLL to be output to the console, which shows that it's empty:

std::vector idx_col = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; std::vector int_col = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };

ULDataFrame df; df.load_data(std::move(idx_col), std::make_pair("IntCol", int_col));

df.write<std::ostream, int>(std::cout, io_format::csv2);

Work(df);

Attached is the output.

DataFrameOutput
hosseinmoein commented 2 years ago

The line in the DLL that prints the data has the wrong type in it. Your column type is int not double

df.write<std::ostream, double>(std::cout, io_format::csv2);

should be

df.write<std::ostream, int>(std::cout, io_format::csv2);
TL4903 commented 2 years ago

While I agree that this is a stupid/silly mistake when writing the sample program, the problem still persists. I changed my program to output to file and I still see the issue.

ULDataFrame                 df;
df.load_data(std::move(idx_col), std::make_pair("IntCol", int_col));

Exec: df.write<std::ostream, int>(std::cout, io_format::csv2); df.write<double, int, std::string, hmdf::DateTime>("C:\temp\DataFrame\INPUT.txt", io_format::csv2);

Work(df);

DLL cpp:

DATAFRAMEWORKDLL_API BOOL __cdecl Work(ULDataFrame& df) { df.write<std::ostream, int>(std::cout, io_format::csv2); df.write<double, int, std::string, hmdf::DateTime>("C:\temp\DataFrame\OUTPUT.txt", io_format::csv2);

return TRUE; }

hosseinmoein commented 2 years ago

So writing to cout in DLL works , but writing to file in DLL doesn't work? what happens? exceptions? empty file?

BTW, you just need this

df.write<int>("C:\temp\DataFrame\INPUT.txt", io_format::csv2);
TL4903 commented 2 years ago

Neither writing to cout or file in the DLL fails, it just shows no column output. I'm just using it to illustrate that the HeteroVector is empty.

Attached are the input/output files. INPUT.txt OUTPUT.txt

hosseinmoein commented 2 years ago

Then it is kind of behind my expertise. Are you running the codebase in master or one of the releases? Since Release 1.20.0, widows compiling became much more organized. That was contributed by @SpaceIm . Maybe he can help? Also, take a look at file DataFrameExports.h. See if that helps to give you a clue.

TL4903 commented 2 years ago

Ok, thanks for your help

hosseinmoein commented 2 years ago

https://stackoverflow.com/questions/22797418/how-do-i-safely-pass-objects-especially-stl-objects-to-and-from-a-dll

hosseinmoein commented 2 years ago

@TL4903 , I am going to close this. But if you find a solution to this, please drop a note here for other people with similar issues