Using BoostTest with C++/CLI : possible or not? - c++-cli

I have a Visual Studio project containing the code of a program (a model). I have created an other project to put the boost tests in it.
The problem is that I can't get it to work.
I can use the boost tests alone in the project, but as soon as I want to link (reference, etc) to the first project (the one I want to run the tests on), the boost test project won't compile :
1>E:\boost_1_53_0\boost/detail/interlocked.hpp(99): warning C4164: '_InterlockedExchange' : fonction intrinsèque non déclarée
1>E:\boost_1_53_0\boost/detail/interlocked.hpp(100): warning C4164: '_InterlockedExchangeAdd' : fonction intrinsèque non déclarée
1>E:\boost_1_53_0\boost/smart_ptr/detail/spinlock_w32.hpp(62): error C3861: '_InterlockedExchange' : identificateur introuvable
I read there that you can't
your code is not C++ but "C++ CLI" and thus you cant use boost. C++ does not have a System namespace. In each .cpp file you can either use C++/CLI (and therefore the System namespace) OR boost. If you want to use the System namespace you have to enable the "Common Langauge Runtime Support", for boost you have to disable it
>> Can anyone confirm that it is not possible to use Boost with a C++/CLI program ?

Yes, it is possible.
First you have to change your C++/CLI project to /clr (/clr:pure or /clr:safe won't work). This allows your project to run in mixed mode, i.e. to run both native C++ and managed code.
Read more on msdn.microsoft.com
Set up Boost.Test for Visual Studio (add the path to the .h of Boost, and add the .lib path in the linker ; you might have to compile Boost because in some cases it's not "header only") ; here is a good tutorial itee.uq.edu.au
That's it, you can write and compile your tests.
However, due to a bug in the compiling (linking, most likely) process of the C++/CLI code and Boost, I haven't been able to put the Boost tests in a different project ; so I had to put the unit tests within the code of the program itself (in seperate .cpp files though, which is an acceptable solution).

The basic problem is that in C++ (non-CLI) code like boost, you cannot hold any managed references or pointers.
I have found that for C++/CLI code, it's usually preferable to use a C# testing framework. C# can talk to the C++/CLI part, which can talk to the pure C++ part. In addition, most use-cases for C++/CLI are wrapping C++ or C code for .Net, so it's a natural choice to test the interface that .Net can see.
As an example, I have a project where all the interfaces are specified in C#. Some implementations use C++/CLI and call into the boost libraries, others are pure C#. The unit tests are generic, with the generic parameter being the actual implementation under test.
Example for MSTest/vstest:
public class MyTest< T > where T : IMyInterface
{
[TestMethod]
public void foo() {...}
}
[TestClass]
public class TestCppCli : MyTest< CppCliImpl > {}
[TestClass]
public class TestCSharp : MyTest< CSharpImpl> {}

Related

Interface Builder is not able to find classes in a static library

Interface Builder is not able to find classes in a static library. It is throwing Unknown MyClassName in Interface Builder error when I run the application. Please note that I am using this class in the controller but still seeing this behavior in Xcode 4.6+.
This solution works but I can't add 30+ categories for as many classes in the static library. It looks uglier when you have multiple static libraries: Xcode 4, Interface Builder and the Awareness of Classes in a Static Library
The best one I've been able to find so far is to add [MyClassName class]; calls in my main method for each one of the static library classes to force Xcode to load them but again it requires all those "class" statements in the main which I am trying to avoid.
Adding "all_load" to linker flag works too but causes tons of files getting included in the build.
Just wondering if anybody knows of a better and cleaner way to deal with this mess?

Including headers from an unmanaged C++ code inside C++/CLI code

I'm writing a CLR wrapper for an unmanaged C++ library.
There are two files I'm including from the unmanaged lib:
//MyCLIWrapper.h
#include "C:\PATH\TO\UNMANAGED\Header.h"
#include "C:\PATH\TO\UNMANAGED\Body.cpp"
Then I'm writing CLI implementations for the unmanaged library functions:
//MyCLIWrapper.h
// includes ...
void MyCLIWrapper::ManagedFunction()
{
UnmanagedFunction(); // this function is called successfuly
}
However, if my Unmanaged function contains calls to other functions that are defined in other unmanaged header files. This causes a compiler linkage error.
If I add includes to the unmanaged headers that define these functions, my errors get resolved. However, there is a lot of functions, and a lot of includes required.
Is there a different way to approach this?
EDIT:
P.S.
My managed code is in a separate Visual Studio project (output - DLL), and the compile settings are set to /CLR. Unmanaged code is in a separate Win32 project (output - DLL).
Also, after more research I concluded that theoretically I could set my Win32 unmanaged project to CLR and just add my managed classes and headers in there as an entry point, and then it would all compile into a single DLL file. That would probably solve (?) the linkage errors. However, I would prefer to preserve the loose coupling as well as the additional series of problems that can raise from setting my unmanaged project to CLR.
EDIT #2:
The unmanaged class that I'm referencing (body.cpp, header.h) contains includes to the required files that define the functions that are causing the problems. However, my managed code doesn't pick up on the includes that are in the unmanaged body.cpp and header.h.
Linker errors are a different kettle of fish from compiler errors. You forgot to document the exact linker errors you see, but a very common mishap when you compile code with /clr in effect is that the default calling convention for non-C++ member function changes. The default is __clrcall, a convention that's optimized for managed code. While functions compiled without /clr defaults to __cdecl. Which changes the way the function name is mangled. You see this back in the linker error message, is shows that it is looking for a __clrcall function and can't find it.
You'll need to either explicitly declare your functions in the .h file with __cdecl. Or tell the compiler that these functions are not managed code. Which is the best way to tackle it:
#pragma managed(push, off)
#include "unmanagedHeader.h"
#pragma managed(pop)
Solution was fairly simple:
I added both unmanaged and managed projects to a single solution in Visual Studio.
Set the unmanaged project's "Configuration Type" to "Static Library" (.lib).
Right click on the managed project -> References -> Add Reference -> Projects -> -> Add Reference.
Then in my managed class, I include the header.h (only) just like I did in my question.
Compiled successfully!
Thank you

GTest not finding tests in separate compilation units

I've got a program written in C++, with some subfolders containing libraries linked in. There's a top level SConscript, which calls SConscript files in the subfolders/libraries.
Inside a library cpp, there is a GTest test function:
TEST(X, just_a_passing_test) {
EXPECT_EQ(true, true);
}
There is main() in the top level program source, which just calls GTests main, and has another GTest test within it:
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
TEST(Dummy, should_pass){
EXPECT_EQ(true, true);
}
Now the issue is that when I run the program, GTest only runs the test in the main.cpp source. Ignoring the test in the library. Now it gets bizarre when I reference an unrelated class in the same library cpp in main.cpp, in a no side-effect kind of way (eg. SomeClass foo;), the test magically appears. I've tried using -O0 and other tricks to force gcc to not optimize out code that isn't called. I've even tried Clang.
I suspect it's something to do with how GTest does test discovery during compilation, but I can't find any info on this issue. I believe it uses static initialization, so maybe there's some weird ordering going on there.
Any help/info is greatly appreciated!
Update: Found a section in the FAQ that sounds like this problem, despite it referring specifically to Visual C++. Which includes a trick/hack to force the compiler to not discard the library if not referenced.
It recommends not putting tests in libraries, but that leaves me wondering how else would you test libraries, without having an executable for every one, making quickly running them a pain and with bloated output.
https://code.google.com/p/googletest/wiki/Primer#Important_note_for_Visual_C++_users
From the scene-setting one gathers that the library whose gtest test case
goes missing is statically linked in the application build. Also that the
GNU toolchain is in use.
The cause of the problem behaviour is straightforward. The test
program contains no references to anything in the library that contains
TEST(X, just_a_passing_test). So the linker doesn't need to link any
object file from that library to link the program. So it doesn't. So the
gtest runtime doesn't find that test in the executable, because it's not there.
It helps to understand that a static library in GNU format is an archive
of object files, adorned with a house-keeping header block and a global symbol table.
The OP discovered that by coding in the program an ad hoc reference to
any public symbol in the problem library, he could "magically" compel its
test case into the program.
No magic. To satisfy the reference to that public symbol, the linker is
now obliged to link an object file from the library - the one that contains
the definition of the symbol. And the OP imparts that the library is made
from a .cpp. So there is only one object file in the library, and it
contains the definition of the test case, too. With that object file in the
linkage, the test case is in program.
The OP twiddled in vain with the compiler options, switching from GCC to clang,
in search of a more respectable way to achieve the same end. The compiler is
irrelevant. GCC or clang, it gets its linking done by the system linker, ld
(unless unusual measures have been taken to replace it).
Is there a more respectable way to get ld to link an object file from a
static library even when the program refers to no symbols in that object file?
There is. Say the problem program is app and the problem static library is
libcool.a
Then the usual GCC commandline that links app resembles this, in the relevant
points:
g++ -o app -L/path/to/the/libcool/archive -lcool
This delegates a commandline to ld, with additional linker options and
libraries that g++ deems to be defaults for the system where it finds itself.
When the linker comes to consider -lcool, it will figure out this is a request
for the archive /path/to/the/libcool/archive/libcool.a. Then it will figure
out whether at this point it has still got any unresolved symbol references in hand
whose definitions are compiled in object files in libcool.a. If there are
any, then it will link those object files into app. If not, then it links
nothing from libcool.a and passes on.
But we know there are symbol definitions in libcool.a that we want to
link, even though app does not refer to them. In that case, we can tell
the linker to link the object files from libcool.a even though they are
not referenced. More precisely, we can tell g++ to tell the linker to do that,
like so:
g++ -o app -L/path/to/the/libcool/archive -Wl,--whole-archive -lcool -Wl,-no-whole-archive
Those -Wl,... options tell g++ to pass the options ... to ld. The --whole-archive
option tells ld to link all object files from subsequent archives, whether they
are referenced or not, until further notice. The -no-whole-archive tells the
ld to stop doing that and resume business as usual.
It may look as if -Wl,-no-whole-archive is redundant, as it's the last thing on the
g++ commandline. But it's not. Remember that g++ appends system default libraries
to the commandline, behind the scenes, before passing it to the ld. You definitely
do not want --whole-archive to be in force when those default libraries are linked.
(The linkage will fail with multiple definition errors).
Apply this solution to the problem case and TEST(X, just_a_passing_test)
will be executed, without the hack of forcing the program to make some no-op
reference into the object file that defines that test.
There's an obvious downside to this solution in the general case. If it happens that the library from
which we want to force linkage of some unreferenced object file contains a
bunch of other unreferenced object files that we really don't need.
--whole-archive links them all of them too, and they're just bloat in the program.
The --whole-archive solution may be more respectable that the no-op reference
hack, but it's not respectable. It doesn't even look respectable.
The real solution here is just to do the reasonable thing. If you want the
linker to link the definition of something in your program, then don't keep that a secret from
the linker. At least declare the thing in each compilation unit where you
expect its definition to be used.
Doing the reasonable thing with gtest test-cases involves understanding that
a gtest macro like TEST(X, just_a_passing_test) expands to a class definition,
in this case:
class X_just_a_passing_test_Test : public ::testing::Test {
public:
X_just_a_passing_test_Test() {}
private:
virtual void TestBody();
static ::testing::TestInfo* const test_info_ __attribute__ ((unused));
X_just_a_passing_test_Test(X_just_a_passing_test_Test const &);
void operator=(X_just_a_passing_test_Test const &);
};
(plus a static initializer for test_info_ and a definition for TestBody()).
Likewise for the TEST_F, TEST_P variants. Consequently, you can deploy these
macros in your code with just the same constraints and expectations that would
apply to class definitions.
In this light, if you have a library libcool defined in cool.h, implemented in cool.cpp
and want gtest unit tests for it, to be executed by a test program tests
that is implemented in tests.cpp, the reasonable thing is:-
Write a header file, cool_test.h
#include "cool.h" in it
#include <gtest/gtest.h> in it.
Then define your libcool test cases in it
#include "cool_test.h" in tests.cpp,
Compile and link tests.cpp with libcool and libgtest
And it's obvious why you wouldn't do what the OP has done. You would not define
classes that are needed by tests.cpp, and not needed by cool.cpp, within cool.cpp
and not in tests.cpp.
The OP was averse to the advice against defining the test cases in the library
because:
how else would you test libraries, without having an executable for every one,
making quickly running them a pain.
As a rule of thumb I would recommend the practice of maintaining a gtest executable
per library to be unit-tested: running them quickly is painless with commonplace automation tools
such a make, and it's far better to get a pass/fail verdict per library than
just a verdict for a bunch of libraries. But if you don't want to do that there's still nothing to the
objection:
// tests.cpp
#include "cool_test.h"
#include "cooler_test.h"
#include "coolest_test.h"
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Compile and link with libcool, libcooler, libcoolest and libgtest

How to expose templates from a C++ to C# via C++/CLI

I want to expose a C++ library to a C# application and I decided to take the C++/CLI wrapper approach instead of P/Invoke. The problem that I am now facing is how to expose a templated class in the C++ lib to the C# application using generics.
On the C++ side I have:
template <typename T> class Someclass;
And my goal is to be able to expose the following type to the C# app
class Someclass<T> {}
So the question now is how should my C++/CLI wrapper look like. I tried the naive approach and created a templated type in C++/CLI and naturally I wasnt able to instantiate the class in C# with generic parameters. And if I expose the class as a generic class I wont be able to pass it to C++.
Disclaimer: I am a C++ newbie so please be gentle :)
I am familiar with the differences between generics and templates so no need to explain those. I have this bad feeling that what I want isn't doable, but since I am relatively new to C++ I hope I can somehow achieve it.
AFAIK: You'll have to write a C++ generic.
http://www.codeproject.com/KB/mcpp/cppcligenerics.aspx
I don't see how the C# application would even understand the template being as that is calculated at compile time, so the C# application wont see templates in the DLL.

Why do we still need a .lib stub file when we've got the actual .dll implementation?

i'm wondering why linkers can not do their job simply by consulting the information in the actual .dll files that got the actual implementation code ? i mean why linkers still need .lib files to do implicit linking ?
are not the export and relative address tables enough for such linking ?
is there anyway by which one can do implicit linking using only the .dll without the .lib stub/proxy files ?
i thought the windows executable loader would simply do LoadLibrary/LoadLibraryEx calls on behalf of the program (hence the name implicit linking) which is the main difference to explicit linking. if that is true then doing it explicitly without .lib should indicate that it is doable without it implicitly, right ? or i'm just saying non sense?
I can think of a a few reasons.
Using .lib files mean you can build for a different version of a DLL than you have on your system, provided you just have the correct SDK installed.
Compilers & linkers need to support cross-platform compilations - You might be building for a 64-bit target on a 32-bit platform and vice-versa and not have the correct architecture DLL present.
.lib files enable you to "hide" certain parts of your implementation - you could have private exports that do not show up in the .lib but are discoverable via GetProcAddress. You can also do ordinal exports in which case they don't have a friendly name exported, but would have a friendly name in the .lib.
Native DLL's do not have strong names, so it may be possible to pick up the wrong version of the DLL.
And most importantly, this technology was designed in the 1980's. If it were designed today, it'd probably be closer to what you describe - for instance, .NET you just need to reference the target assembly and you have everything you need to use it.
I don't know of any way to do implicit linking solely with the DLL - A quick search revealed several tools, but I haven't used any of them.
In this case, I would create a separate source file with the functions you need to use, and dynamically load the DLL and bind them as needed. For example:
// using global variables and no-error handling for brevity.
HINSTANCE theDll = NULL;
typedef void (__stdcall * FooPtr)();
FooPtr pfnFoo = NULL;
INIT_ONCE initOnce;
BOOL CALLBACK BindDLL(PINIT_ONCE initOnce, PVOID parameter, PVOID context)
{
theDll = LoadLibrary();
pfnfoo = GetProcAddress(dll, "Foo");
return TRUE;
}
// Export for foo
void Foo()
{
// Use one-time init for thread-safe lazy initialization
InitOnceExecuteOnce(initOnce, BinDll, NULL, NULL)
pfnFoo();
}