Including C++ sources in a Haskell project - c++

I'm trying to make a data structure that will be exposed in Haskell, but implemented in C++. So far I've implemented it in a .cpp file, declared all the functions I need as extern "C" and added the source file to the c-sources field in the .cabal file. When I build the project (in this case with stack build) it seems to build fine.
I know it's doing something to the C++ file because it doesn't compile if there are errors.
I've yet to try running the project because it's a library and so far it doesn't have anything "runnable" written, but the repl doesn't seem to work.
When I try running it (stack repl in this case) I get a missing symbol error with some mangled name that may or may not be refer to a name in my file.
unknown symbol `_ZdlPv'
linking extra libraries/objects failed
How can I fix this issue? I've had a similar problem before that I fixed by manually compiling the source into a dynamic library and then use that library in my project. I don't want to do that since it ties me to a platform and since it makes no sense that a simple C++ couldn't be compiled with the project using the tools that GHC already has. I want to be able to put this on hackage.
Is there something I'm missing? If not, is it a bug and are there plans on fixing it?

Ok, I've managed to "fix" this for now.
I added a extra-libraries: stdc++-6, gcc_s_seh-1 to my cabal file and now it works. No idea if this is platform independant but those libraries do get shipped with GHC when I install it through stack.

Related

Building MuPdf and registering document handlers

Here we have a question, an answer and some happy people.
But I've got a different situation,
I'm coding in C++ and I'm going to build MuPdf myself.
So, when i add fz_register_document_handlers function before fz_open_document_with_stream I'll get 5 unresolved external symbols for these
_opj_image_destroy (2 times)
_opj_copy_image_header
_opj_image_comp_header
_opj_image_create
I can get rid of 3 of them by linking openjpeg\libopenjpeg\image.c but _opj_image_destroy is stock on my compiling error list!
[UPDATE]
Mupdf version: 1.6
I don't know that it's a right way or not but I created a visual studio project, named Native and put Mupdf source in it and try to compile.
Then i'm using it's header in other c++ project (and using declare "C" in it) and linked Native to it.
It works fine until i trying to open a file as a stream and not file address.
So, my project failed with this error: "No document handlers registered".This error is caused by document.c file.
I searched and find the page which was linked above and I changed the source.
The compile errors appeared after that change!
Thanks for your help and sorry for my English...
Firstly, you haven't said what version of MuPDF you are using. I'm going to assume you're using the latest version from git (currently 1.6 as of 1 Feb 2015).
Secondly, you've not told us anything of use about how you're building MuPDF. Without knowing exactly what you've changed, it's hard to speculate what you're doing wrong.
If you're compiling vanilla .c files with a c++ compiler then you probably need to do some wrapping of files with extern "C" declarations.
Feel free to get in touch on the #ghostscript irc channel and tell us more.
[Update]
It sounds to me like you are missing the openjpeg decoder. You can't just add a single file from the openjpeg source and expect it to magically work.
Why are you creating your own Visual Studio project when we provide one for you already? platform/win32/mupdf.sln

How to convert a cmake project into a Visual Studio equivalent?

The situation is the following: I have the source code of one programm (lets call it programA) (written in C and C++), as well as the CMakeLists.txt and CTestConfig.cmake files. I already installed programA using CMake's graphical user interface and, as it is obvious, it worked. It created the .exe file (I'm working on Windows 7 OS).
The problem is that, right now, I've been asked to edit the program (and so, I must be able to edit the code and degugging it as changes are made). I also need to compile it but not in .exe anymore but in .dll so I can add it to a website we have.
I've read in forums that CMake can compile programA into a .dll if I need to, but as I would need to make some changes I consider that CMake debugging is not as useful and easy as using entirely VS. From the little I know from CMake language, the CMakeLists.txt is mainly used to check the OS of the user as well as adding some libraries in case they are not found.
I have to admit I have no idea in programming CMake directives, as I have been working with ASP.NET, C, C++ and C# mostly. Then, my idea is to try to work only in visual studio 2010 instead of using cmake as well, so once I have the program 'adapted' to VS and can be compiled just using VS, I'm ready to start my job. So the question I have is how can I perform the same task CMake did just using Visual Studio (Is there any way of implementing CMake directives in VS?), can VS compile by receiving as an argument something similar to that CMake.txt file (though it needs to be translated into another language)?
To skip the use of CMake I tried to copy the source code into a new project in VS. However as it does not use the CMake directives when compiling, it gives several errors, most of them related to the fact that some headers.h can't be found (cause they might be in a subfolder). And there are so many subfolders to add the paths to the predefined directories of search that it would take ages.
I'm sorry I can't be more precise in my explanation. I'm good at programming little projects on my own, but it's the first time I have to work on other's programm. Please don't hesitate to ask if anything was not properly understood
I would appreciate a lot any suggestion / advice /guidance you can give.
To make a dll, use add_library command and the SHARED keyword
add_library(mylib SHARED ${files})
this is easy with CMake, don't go back in visual that will be harder at the end
The Good News
Fortunately, cmake can generate VS Projects automaticaly for you (this tutorial s specific for OpenTissue, but Steps 1 to 3 should be the same for you).
The [not so] Bad News
Depending on the complexity of the project, VS Projects automaticaly generated by cmake can get pretty nasty, to the point of illegibility. It will, for example, hard link any library dependencies using the specific paths of your machine, so the project will most certainly not be portable across setups. In any case, that's the intended bahavior, because the primary idea of supporting this generator is simply making it work, thus allowing users to easily compile projects using MSVC, so there's not much you can do here. Nonetheless, it should work in your machine and will certainly be a great starting point for you, just create a project yourself from scratch copying the relevant parts out of the automatic generated version.

C++ boost thread is missing from your computer

I'm having this very strange problem when I try to run my program on code blocks using a g++ compiler. I have installed boost AND used it up until perhaps a week ago, I never had any problems. Today, I returned to a project I was working on and suddenly I get the following error message when I try to run it
The program can't start because libboost_thread-mgw47-mt-1_53.dll is missing from your computer. Try reinstalling the program to fix this problem.
Now I've used boost thread before in this program, so I have no idea why I'm getting this. What's also strange is that boost threads work in other projects I have.
How do I go about trying to solve this? Everything seems to be in place, path variables set, compiler, linker options set, etc... Nothing, that I'm awawre of, has been changed since the last time I ran this program successfully. I did update Visual Studio today, but I don't think that should have any effect. I'm not really sure what other information I can give since I have no idea why this is happening. The .dll file does certainly exist, I've tried moving it into the working directory but still get the same error.
Anyone have any suggestions on how I can go about solving this?
Your compiler in that project is dynamicly linking the boost thread library,
Probably some misconfigured settings in linker options or your code uses dllimport instead of 'normal' functions which are resolved at compile-time (dllimport resolves functions at runtime - it can't find them in the required library so you get an error).
Your other projects work because they staticly link the boost thread library (provide the corret boost preprocessor definisions for static linking/compiling and include the corresponding cpp/lib files for the thread library) so it's included in the program.
So I figured it out. (note again, I'm using code blocks)
I had everything set up in the global compiler and linker settings (which I thought would enough). I had everything set up in the individual projects compiler settings, but the project that was working also had some extra stuff in the linker settings. So I had everything set, EXCEPT the settings in the Project -> Build Options -> Search Directories -> Linker part, with the project name selected, not debug/release. I added in...
$(#boost.lib)
............\boost_1_53_0\stage\lib
and now it's fine.
Sort of surprised that the global compiler settings doesn't cover the individual project settings, but there you go.

Multiple definitions of main

how do I correctly implement Lua in a C++ program? I downloaded the Lua source, put the .c files in my src folder and the .h files in my include folder, included lua.h in my program's source code (with extern "C"{} of course) and hit "Build".
That's how all the tutorials tell me to use Lua with a C++ project.
But now I get the error "multiple definition of main" and some Symbols in the Lua code that could not be resolved. I understand what the first error means (conflict because Lua has a main and my program also has one), but how can I solve it?
Or did I understand something completely wrong about implementing Lua in a C++ program?
Check to make sure you didn't include luac.c, lua.c, and the source for any other programs that are included with Lua in with your source code. Lua's source includes a few extra utilities (i.e., luac), and chances are you've just included them in the project and forgotten to remove them, thus resulting in having more than one main.
In short, those are separate programs that you don't add to your project. If you can, just build Lua normally, link to the library, and include the header files as normal.
So, on the point of you misunderstanding how to use Lua, you probably did to some degree. It is entirely possible to just copy Lua's source into your code, though probably not advisable. What you really want to do is pull up the extracted Lua source in a terminal and build it. Then (according to Lua's INSTALL document), you'll want to type make platform, where you'll replace platform with whichever platform you're currently using (i.e., I'd use macosx, you might use linux, refer to the INSTALL for which platforms are supported). After that, it's up to you if you want to install it or not, but you'll just do make install (or sudo make install) to get that done.
After that, either add the appropriate linker flags when compiling to link to Lua (e.g., -llua) or alter your project's settings in your editor of choice to do roughly the same thing. That said, you'll want to refer to the INSTALL document provided with Lua for complete instructions on this.
I'm embedding Lua in my projects other way around, preferred way, IMO: compiled Lua as a static library.
Just comment the two main() blocks in Lua.c an Luac.c, then hit build and run again.
I made this on Lua 5.3.

Why can't a "procedure entry point could not be located in dll" when I definitely put it in?

I have a really vague problem, but I hope someone can help with it. I was modifying a C++ project and yesterday it was still working, but today it's not. I'm pretty sure I didn't change anything, but to be completely sure I checked the project out from SVN again and I even reverted to a previous system restore point (because this is a work computer, it sometimes secretly installs updates etc.). After succesfully compiling it, the program can start up, but after I interact with it, I get this error:
The procedure entry point ?methodName#className##UAEXXZ could not be located in the dynamic link library libName.dll.
I've searched the internet, but most people's problems seem to be caused by an older version of the DLL being used. I searched my computer and there is no older version. If I delete the correct version, the application doesn't start. If I then recompile the project, the DLL is created again, so I'm both pretty sure that the application is using the correct DLL and that the compilation is creating it. If I introduce syntax errors into the method that the error refers to, the project refuses to compile, so I guess this means that it is also compiling the files that contain the method.
Basically I don't know anything about DLL's, linking, etc. so I would greatly appreciate it if anybody has an idea as to why the functions that are very clearly defined in the project are all of a sudden not making it into the DLL anymore. I know this is vague and if any more information is required I will gladly provide it. Thanks!
Update: I have tried the given suggestions, but I'm still stuck. __declspec(dllexport) is apparently not used in the entire project. Opening the DLL with Dependency Walker shows me an empty top right section and the section below it lists the function from the error message. If I check Undecorate C++ Functions it looks fine, but if I don't I get the weird question marks and #s from the error message and there appears to be a difference at the end:
?methodName#className##UAEXXZ
?methodName#className##UAEXH#Z
Perhaps this is the problem, but I have no idea what it means, what may have caused this and what I can do about it.
Are you actually using __declspec(dllexport)? My guess is no -- without that declaration, that function will not be exported by the DLL (or in other words, programs loading that DLL will not have access to functions without that declaration).
Also, try using Dependency Walker to see exactly which functions your DLL has made available.
The fact that __declspec(dllexport) isn't used in function declarations is okay -- most of the time, it will only be used once in a single header file, like
#ifdef MAKING_DLL
#define FOO_API __declspec(dllexport)
#else
#define FOO_API
#endif
So that if you have #define MAKING_DLL before that section, all functions that are declared like FOO_API int BakeACake() will be exported based on whether MAKING_DLL was defined. It's possible that the project was expecting MAKING_DLL (or its equivalent) to be defined on the command line, depending on the project type built (something like /DMAKING_DLL; or you might even need to define FOO_API yourself like /DFOO_API=__declspec(dllexport).
The empty top right section in Dependency Walker just means your program isn't linking against the DLL's corresponding .lib file. That's okay, it just means you are using LoadLibrary or LoadLibraryEx to access functions in the DLL.
Another fairly likely scenario (based on the fact that the mangled names are different) is that the program was built using a different version of Visual Studio than 2008, which you used to build the DLL. Unlike plain C, there's no standard binary interface for C++, which means that you have to use the same compiler to build the program and the DLL when you are using C++ classes in the DLL. If you can, try rebuilding the program in VS2008, or try rebuilding the DLL in the same version of VS as the program was built.
Download dependency walker and open your dll using this tool. It will show a list of exported functions from your dll. Check whether the above said method is part of the expected functions. If it's not, then it means you accidentally removed __declspec(dllexport) for one of the classes in that dll.
I feel a bit stupid, but I found the answer. The application (exe) I was using apparently loaded a second, different dll which had a dependency on the one mentioned in my original post. This second dll was still expecting the old functions and also needed to be recompiled against the updated dll.
Many thanks to the people who tried to help me here!
Using information of the posts above I found simple general solution. All you need to do is open programs executable with dependency walker, look for the missing functions, look what dll's are using it, find the project which builds that dll and rebuild it.