Boost.Test as DLL

Hi, I am trying to finally implement DLL version of Boost.Test components. Here is several issues/questions I have: 1. main() function AFAIK there is no way to put a main function in DLL on windows. What should we do instead? I reworked the framework specifically for the purpose of making this kind of separation easier. But I still would like to hear what people think in this regard. 2. main() function again On unix(s) there is a possibility to put main info dlls (If I am wrong please correct me). Should we use different semantic for Windows and Unix(s) or use the one I implement for windows? 3. init_unit_test_suite I need to call external function from inside of DLLs. How it should be declared? Cause I am getting unresolved symbols error 4. runtime-link In my Jamfile in default build section of build rule there is <runtime-link>static/dynamic. Should I keep this? Should I use static for lib rule and dynamic for dll rule? Nothing for lib dynamic for dll? Thanks, Gennadiy

Gennadiy Rozental wrote:
Hi,
I am trying to finally implement DLL version of Boost.Test components. Here is several issues/questions I have:
1. main() function
AFAIK there is no way to put a main function in DLL on windows. What should we do instead? I reworked the framework specifically for the purpose of making this kind of separation easier. But I still would like to hear what people think in this regard.
The equivalent to an entry point routine in a DLL is most often called DllMain or DllEntryPoint with some compilers. There are many things one can not do in the Dll entry point and it is used just as a way of initializing the Dll. If you need some function that actually serves to call other functionality in a Dll as if you had a main() routine in an exe, pick out whatever name you think appropriate, add it as a function in your Dll and export it so that it can be called from outside the Dll.
2. main() function again
On unix(s) there is a possibility to put main info dlls (If I am wrong please correct me). Should we use different semantic for Windows and Unix(s) or use the one I implement for windows?
3. init_unit_test_suite
I need to call external function from inside of DLLs. How it should be declared? Cause I am getting unresolved symbols error
Most Windows compilers support __declspec(dllexport) or __declspec(dllimport) in front of a function or class name and it is used like: #if defined(BUILD_MY_DLL) #define MY_DLL_IMPORT_EXPORT_MACRO __declspec(dllexport) #elif defined(USE_MY_DLL) #define MY_DLL_IMPORT_EXPORT_MACRO __declspec(dllimport) #else #define MY_DLL_IMPORT_EXPORT_MACRO __declspec(dllimport) #endif and then for some function or class you want to export/import you write: MY_DLL_IMPORT_EXPORT_MACRO void SomeFunction(); or MY_DLL_IMPORT_EXPORT_MACRO class SomeClass { // etc. }; Often USE_MY_DLL can be defined internally depending on whether you can figure out whether or not the module is being used as a DLL or a static library, else the user can be required to define it or not.
4. runtime-link
In my Jamfile in default build section of build rule there is <runtime-link>static/dynamic. Should I keep this? Should I use static for lib rule and dynamic for dll rule? Nothing for lib dynamic for dll?

Edward Diener wrote:
Gennadiy Rozental wrote:
3. init_unit_test_suite
I need to call external function from inside of DLLs. How it should be declared? Cause I am getting unresolved symbols error
Most Windows compilers support __declspec(dllexport) or __declspec(dllimport) in front of a function or class name and it is used like:
#if defined(BUILD_MY_DLL) #define MY_DLL_IMPORT_EXPORT_MACRO __declspec(dllexport) #elif defined(USE_MY_DLL) #define MY_DLL_IMPORT_EXPORT_MACRO __declspec(dllimport) #else #define MY_DLL_IMPORT_EXPORT_MACRO __declspec(dllimport) #endif
and then for some function or class you want to export/import you write:
MY_DLL_IMPORT_EXPORT_MACRO void SomeFunction();
I think Gennadiy wants the dll code to call a user-defined function, and the problem is that if you declare the function and then leave it undefined the linker complains, even though this works fine with static linking, since the user supplies the definition and the linker sees everything at once. Jonathan

Jonathan Turkanis wrote:
Edward Diener wrote:
Gennadiy Rozental wrote:
3. init_unit_test_suite
I need to call external function from inside of DLLs. How it should be declared? Cause I am getting unresolved symbols error
Most Windows compilers support __declspec(dllexport) or __declspec(dllimport) in front of a function or class name and it is used like:
#if defined(BUILD_MY_DLL) #define MY_DLL_IMPORT_EXPORT_MACRO __declspec(dllexport) #elif defined(USE_MY_DLL) #define MY_DLL_IMPORT_EXPORT_MACRO __declspec(dllimport) #else #define MY_DLL_IMPORT_EXPORT_MACRO __declspec(dllimport) #endif
and then for some function or class you want to export/import you write:
MY_DLL_IMPORT_EXPORT_MACRO void SomeFunction();
I think Gennadiy wants the dll code to call a user-defined function, and the problem is that if you declare the function and then leave it undefined the linker complains, even though this works fine with static linking, since the user supplies the definition and the linker sees everything at once.
OK, but would it not be better just to use boost::function<> to allow the user to pass in a user-defined function at run-time from wherever he chooses ? This is much more flexible than attempting to declare a user-defined function in a Dll which the end-user is supposed to define and depend on compile/link to resolve it..

I think Gennadiy wants the dll code to call a user-defined function, and the problem is that if you declare the function and then leave it undefined the linker complains, even though this works fine with static linking, since the user supplies the definition and the linker sees everything at once.
OK, but would it not be better just to use boost::function<> to allow the user to pass in a user-defined function at run-time from wherever he chooses ? This is much more flexible than attempting to declare a user-defined function in a Dll which the end-user is supposed to define and depend on compile/link to resolve it..
Flexibility point aside this is the way static version is working. I just looking for solution to do the same with dll. As for callback based interface (another thing is that I couldn't depend on boost::function) your proposition would complicate users interface: one need not only define the init function itself but she also has to write main function itself that invoke the framework and pass this callback (or another function I would call from main myself but this would be catch-22) Gennadiy

Gennadiy Rozental wrote:
As for callback based interface (another thing is that I couldn't depend on boost::function) your proposition would complicate users interface: one need not only define the init function itself but she also has to write main function itself that invoke the framework and pass this callback (or another function I would call from main myself but this would be catch-22)
Maybe a macro version of init_unit_test_suite would be acceptable. Invocation could look like: INIT_UNIT_TEST_SUITE(int, char* []) { test_suite* test = BOOST_TEST_SUITE("test name"); // add tests return test; } This could expand to ::boost::unit_test_::test_suite* init_unit_test_suite(int, char* []); int main(int, char* []) { // register callback, run framework, return result } ::boost::unit_test_::test_suite* init_unit_test_suite(int, char* []) { test_suite* test = BOOST_TEST_SUITE("direct_adapter test"); // add tests return test; } Jonathan

Edward Diener wrote:
Jonathan Turkanis wrote:
I think Gennadiy wants the dll code to call a user-defined function, and the problem is that if you declare the function and then leave it undefined the linker complains, even though this works fine with static linking, since the user supplies the definition and the linker sees everything at once.
OK, but would it not be better just to use boost::function<> to allow the user to pass in a user-defined function at run-time from wherever he chooses ? This is much more flexible than attempting to declare a user-defined function in a Dll which the end-user is supposed to define and depend on compile/link to resolve it..
This is really a question for Gennadiy, but I believe the answer is that he wants the use of the library as a dll to be as close as possible to the current use as a static library. Jonathan

"Gennadiy Rozental" <gennadiy.rozental@thomson.com> wrote in message news:cvhbfi$7pu$1@sea.gmane.org...
Hi,
I am trying to finally implement DLL version of Boost.Test components. Here is several issues/questions I have:
[...]
2. main() function again
On unix(s) there is a possibility to put main info dlls (If I am wrong please correct me). Should we use different semantic for Windows and Unix(s) or use the one I implement for windows?
I don't know about the specifics, but I'd definitely prefer the same semantics (at least from the "end" user's point of view).
3. init_unit_test_suite
I need to call external function from inside of DLLs. How it should be declared? Cause I am getting unresolved symbols error
Linking the DLL isn't different from linking an EXE in this case. You can't link the DLL without having the function definition available at link time. You could solve this using callbacks, but as a DLL can't define main anyway, what are you actually trying to do? Would it be an alternative to have Boost.Test as a DLL, minus the definition of main, which could be provided by e.g. an object (or a static library, but IIRC there's a problem with having main's defined in static libraries on certain compilers/platforms - the linker doesn't recognize there's a main at all)? Just thinking out loud. // Johan

2. main() function again
On unix(s) there is a possibility to put main info dlls (If I am wrong please correct me). Should we use different semantic for Windows and Unix(s) or use the one I implement for windows?
I don't know about the specifics, but I'd definitely prefer the same semantics (at least from the "end" user's point of view).
That would mean changing a semantic from the one I currently support on Unix(s). Though it would be what I prefer to do either.
3. init_unit_test_suite
I need to call external function from inside of DLLs. How it should be declared? Cause I am getting unresolved symbols error
Linking the DLL isn't different from linking an EXE in this case. You can't link the DLL without having the function definition available at link time.
So you are saying there is no way to have external reference in DLL?
You could solve this using callbacks, but as a DLL can't define main anyway, what are you actually trying to do? Would it be an alternative to have Boost.Test as a DLL, minus the definition of main, which could be provided by e.g. an object (or a static library, but IIRC there's a problem with having main's defined in static libraries on certain compilers/platforms - the linker doesn't recognize there's a main at all)?
AFAIK main in static libs works everythere.
Just thinking out loud.
// Johan
Gennadiy

"Gennadiy Rozental" <gennadiy.rozental@thomson.com> wrote in message news:cvknno$qip$1@sea.gmane.org...
2. main() function again
On unix(s) there is a possibility to put main info dlls (If I am wrong please correct me). Should we use different semantic for Windows and Unix(s) or use the one I implement for windows?
I don't know about the specifics, but I'd definitely prefer the same semantics (at least from the "end" user's point of view).
That would mean changing a semantic from the one I currently support on Unix(s). Though it would be what I prefer to do either.
Also?
3. init_unit_test_suite
I need to call external function from inside of DLLs. How it should be declared? Cause I am getting unresolved symbols error
Linking the DLL isn't different from linking an EXE in this case. You can't link the DLL without having the function definition available at link time.
So you are saying there is no way to have external reference in DLL?
I'm saying that, to the best of my knowledge, there is no such way. All referenced must be resolved at link-time, either defined in the DLL itself or in other DLLs via imports.
You could solve this using callbacks, but as a DLL can't define main anyway, what are you actually trying to do? Would it be an alternative to have Boost.Test as a DLL, minus the definition of main, which could be provided by e.g. an object (or a static library, but IIRC there's a problem with having main's defined in static libraries on certain compilers/platforms - the linker doesn't recognize there's a main at all)?
AFAIK main in static libs works everythere.
I definitely had a problem on DEC C++ 6.5-<something> on OpenVMS Alpha. Linking would appear to work normally, but the application always bombed on startup until I moved main into my application. It might have been possible to resolve using some special compiler and/or linker settings, but I was under pressure to get things working. // Johan
participants (4)
-
Edward Diener
-
Gennadiy Rozental
-
Johan Nilsson
-
Jonathan Turkanis