Related
I am upgrading my preexisting CAD/CAM project (quite big one > 10MByte of code) and have to add some special measuring equipment. The problem is I have more than one supplier of the measuring system (although is already decided which one to use) and I want to configure them (using #define in case vendor is changed in future) with code to use only selected device type. So I have something like:
#define use_vendor1
//#define use_vendor2
//#define use_vendor3
and some of the vendors APIs require their own DLLs so I need for example:
Project/Add to project/vendor1.lib
Project/Remove from project/unused_vendor.lib
if use_vendor1 is used ... That will be uncomfortable to add/remove each type reconfiguration of exe is required. I was wondering if there exist a way similar to this:
#ifdef use_vendor1
#pragme link "vendor1.lib"
#endif
That one does not work of coarse because DLL *.lib is not compiled code as *.obj ...
Having all the libs in the project is an option but that would require shipping exe with all the DLL's which I would rather avoid.
Another option would be dynamic DLL link but I rather avoid it as that is more coding for me in it...
I am bound to old BDS2006 Turbo C++ Explorer IDE and compiler.
Also is it possible to statically link DLL in relative path to EXE ?
You are looking for #pragma comment:
#ifdef use_vendor1
#pragma comment(lib, "vendor1.lib")
#endif
I am giving Gwan a whirl.
Having made it through example code, I started a small project with more than one source file. I now have two problems:
I got a linking error at server startup:
Linking main.cpp: undefined symbol: _ZN7GwanUrl9concatAllEv
(the main file #includes the two other files; all the files are in the csp directory)
As an alternative to having all the files in the /csp directory, I would like to make a library outside of the /csp directory while still using some of the gwan functions. sadly, a tonne of errors follow -- WHEN I GCC from commandline not via G-WAN Startup.
In file included from /home/ec2-user/gwan/include/gwan.h:22,
from Xbufstream.h:10,
from Xbufstream.cpp:10:
/usr/include/time.h:199: error: ‘size_t’ does not name a type
.....
Anyone knows what the gwan g++ argument string looks like?
(odd the 1. and 1. its 1. and 2. in the editor)
First, this is not a linker issue: you have "undefined symbol" rather than "unresolved symbol" as an error.
This is simply an #include issue.
define the main() function in your script.cpp file.
there's a G-WAN folder dedicated to user-defined include files called /gwan/include but you can as well use /csp/my_include.hpp... if you are using the right syntax:
For example, having #include "toto.hpp" in /csp/hello.cpp lets me reach C++ functions defined and implemented in the gwan/include/toto.hpp file (or defined in toto.hpp and implemented in a pre-compiled library linked to your script with #pragma link).
If you rather use #include <toto.hpp> then the SYSTEM INCLUDE PATH will be searched instead (and this will work providing that your library was correctly installed).
If you want to use #include "toto.hpp" for a custom folder that was not setup in the system, you can use G-WAN's #pragma include "../my_folder" directive to specify its PATH or you can explicitely specify it in each include: #include "../my_folder/toto.hpp".
Nothing fancy there, only C/C++ dependancy rules apply (and G-WAN really helps by providing alternate ways that do not involve system settings).
For libraries (see the G-WAN examples for SQLite, Cairo, mySQL, cURL, etc.) you can either use pre-installed libraries that exported their location in SYSTEM variables... or put your library in the /gwan/libraries folder and their include file in the /gwan/include folder.
When writing your own libraries, remember that they need to be pre-compiled. This means that you obviously cannot use G-WAN symbols since your compiler may #include "gwan.h" (to have the definitions) but your linker will not know from where G-WAN symbols can be found. The way around is to always use the G-WAN API from the G-WAN scripts. Your custom libraries must either be general-purpose or buffer any payload intended to be used by G-WAN. No-double copy is needed since G-WAN provides the set_reply() call to let G-WAN use persistent replies built without the reply xbuffer provided by G-WAN servlets.
Now, a last word about linking (which was not the cause of your trouble but could participate to the confusion). If you mix C and C++, use extern C {} to wrap your C++ prototypes called from C (otherwise you will really have "unresolved symbols").
With all this information, you should be ready to face every possible situation.
the issue of referencing gwan.h symbols inside #include files can also be solved by moving all code into the header file, whether its .h or .hpp
its ungraceful but a fix nevertheless. and good enough for the simple extension i wanted.
looking into the /libraries/sqlite3/sqlite.h helped.
#gil, thanks for your time.
I inherited a substantial amount of code, including a visual studio project that is supposed to (as best as I can tell) build a .lib file. Visual studio says "... Generating Code... Creating Library... Creating browse information file...", and at the end, it says the build succeeded. In the release/debug folder, it has a bunch of .obj files, but it doesn't have a .lib file. What could I be missing?
Thanks!
Open the Project Properties (right-click the project in Solution Explorer, select 'Properties'). Under 'Librarian', check 'Output File' - that's where the output should go.
If this looks right, try dir /s *.lib in a suitable subdirectory for your project, to see if you can locate the output library by date and time. If you still can't find it, try a clean rebuild (right click project, select 'Rebuild').
For DLLs, a .Lib file is not created if the DLL exports nothing for external usage. I don't think this applies for static lib builds but I would make sure you are exporting something public from your library project source code.
.lib will not get generated if you miss to add prefix __declspec(dllexport) for methods.
My static library contains nothing but two template classes, so I didn't have a .cpp file. This caused Visual Studio 2015 to not output a .lib file. To solve this, I made a file huh.cpp which includes all of the headers.
I had the same problem, even though I was already using the __declspec(dllexport) function.
Your ProjectName.cpp file needs to #include "ProjectName.h". If you don't include the header file then the functions don't get exported. The DLL builds fine, no errors or warnings (at least in VS2017 15.8), but you don't get a LIB file.
Include the header and boom - LIB file is generated. A rookie mistake I'm sure, but everyone has to start learning somewhere.
If the Methods you want to export are in a class, you have to __declspec(dllexport) on the class. Otherwise no .lib will be created.
In my case (Visual Studio 2019), when #include "pch.h" was not the very first include statement in cpp, lib file was not created.
I just ran across this problem as well.
It was due to using an invalid macro in the output directory definition. In my case, it was
when it should have been
I had to blank out the full path in the second screen shot. I had an incorrect macro. I was using MsBuildProjectDir when I should have been using MsBuildProjectDirectory. The read-only text box will show the full path (eg: C:\Development\blah\blah\blah\) when the output directory is valid. If the output directory is not valid, you'll get something like the first screenshot.
In the DLL project, put __declspec(dllexport) beginnings of methods defined in .h and .cpp files.
After all, compile your dll again, so .lib file will be generated and ready for linking.
put Class Foo
{
public:
__declspec(dllexport) int GetFoo() const;
I was exporting a class from the dll but had declared the class inline in .h file. The .cpp file was there but empty. This setup was causing the .lib file to be not generated.
I moved the implementation of functions to .cpp file and now lib file is generated.
This is in VS2019.
Had the same issue here with VS2019. In my case I had built a few times with no symbols defined (i.e. cpp files were empty).
After I added symbol definitions into the cpp files I began to notice this issue (no lib file was being generated).
A simple clean via 'Rebuild all' fixed it. Perhaps if you build whilst there are no symbols defined, something gets cached somewhere that you have an empty product DLL, and you need to clean the solution to reset that cached state.
My issue was that in the projects Properties>C/C++>CommandLine, I had specfied the switch incorrectly.
That is instead of writting /D_HASHING_BUILD_DLL I had written /D_Hashing_BUILD_DLL.
Side note:
This is how I build my DLL/Lib files in Visual studio : (and my Hashing.h looks like this: )
#ifndef HASHING_H
#define HASHING_H
/* If we are we on Windows, we want a single define for it.*/
#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))
#define _WIN32
#endif /* _WIN32 */
#if defined(_WIN32) && defined(_HASHING_BUILD_DLL)
/* We are building Hashing as a Win32 DLL */
#define HASHING_API __declspec(dllexport)
#elif defined(_WIN32) && defined(HASHING_DLL)
/* We are calling Hashing as a Win32 DLL */
#define HASHING_API __declspec(dllimport)
#elif defined(__GNUC__) && defined(_HASHING_BUILD_DLL)
/* We are building Hashing as a shared / dynamic library */
#define HASHING_API __attribute__((visibility("default")))
#else
/* We are building or calling HASHING as a static library */
#define HASHING_API
#endif
//your inlcudes
class HASHING_API MyClass
{
//...
};
#endif // !HASHING_H
and in the path I stated earlier, I just use the switch I defined here and there you go, the DLL is built just fine!
I'm not so familiar with C++ and I had the same issue. I thought I would share what worked for me. It appears that the import/export must come after the class statement, according to the following page.
https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4091?view=msvc-160
// Warning C4091
// No error but didn't produce a .lib file
__declspec(dllimport) class X {};
// __declspec attribute after the class or struct keyword
// applies to user defined type worked
class __declspec(dllimport) X3 {};
Sometimes when you break you head in a new project why .lib is not created - it can be some "past games" issue.
I was creating a new .dll but before I decided to use #define with __declspec(dllexport)/__declspec(dllimport) I tried to play with .def
After removing .def file it probably left some misconfiguration in the project file and it wasn't creating .lib file...
Till I decided to just remove the project completly and recreate - and walla, works perfectly!
I am writing a user-space Win32 application. However, as part of this application I need to make some DeviceIo calls to the Windows 1394 stack. The header file which contains the prototypes for these DeviceIo calls is included as part of the Windows DDK at:
C:\WinDDK\7600.16385.1\inc\api\ntdd1394.h
(Although the header claims to be "Kernel mode only" the prototypes are for user-space IOCTLs.) I am wondering what the best way to include this file in my application is.
It would be poor practice to #include it directly (the path depends, among other things, on the DDK version) and in addition there is no real need for the DDK to be installed --- the only dependency my application has on it is for this very header file.
Hence I am wondering what the best course of action is? I was considering including a stripped-down version of it directly in my applications source but really am not sure.
I'd say include either a stripped down version, or if what your using is really small, import copy it directly into the main header for your project.
regardless which path you take, I'd say wrap both in #define guards, incase someone else who tinkers with this inports the correct header and causes trouble. Even better would be something to allow the user to either define the path to the DDK or use your stripped down version:
#define EXP(x) #x
#define STR(x) EXP(x)
#if defined(__WIN32_DDK_PATH)
#include STR(__WIN32_DDK_PATH)
#else
//Stripped DDK stuff...
#endif
tested the above using gcc 3.4.5(old I know, but dev-cpp is all I have where I am), works fine
How are you linking against the actual implementations of these functions? The documentation for the library you are linking against should tell you what to #include.
Also, do you need other people to be able to build this application or is it a one-man job? You could always set up a virtual build machine which has the DDK installed and #include the file that way.
Otherwise, yes, including the function prototypes in your own stripped down header file (with a comment to say why you are doing this!) is probably the way to go.
This works for me (taken from one of the samples in DDK):
#define _WIN1394_C
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <ntdd1394.h>
#undef _WIN1394_C
Why does C++ Builder 6 always compile all files?
I make some changes on one file but BCB 6 compiles all files when I start the app. Any idea? I use Windows XP SP2.
try this plugin for BCB compiler:
Bcc32Pch IDE Plugin
Are you source files and binary objects located on the same machine? If not sounds like you have a network time sync issue.
If they are its most likely a header file issue, either the compiler include files have a modified date some time in the future or your application is dependent on some header file that changes during compilation say from a COM import.
EDIT: Check the setting VS has a flag to always re-compile, this might be true for BCB too, if set then unset it. Another possibility is that pre-compiled headers are miss-configured to generate on every source file.
I am not familiar with BCB 6 to give a more precise answer.
Have you made all or many of your files dependent on a particular module?
Any files that are dependent on a particular module will be rebuilt any time the module class structure (contained in the .h file) is modified. If, for example, you have a data module that is accessed by many other modules you will see a rebuild of all dependent modules each time the data module's class structure is modified.
There are an pragma in Borland, wich controls how many lines of code is recompiled.
In the past years i have managed (in some project), that only changes of my source are compiled. I don't know, if this will be worked in newer versions of borland
Borland 6 has an pragma "hdrstop".
this is only active, if the project option "Pre-Compile headers" is NOT "none"
years ago I have an very slow computer an i accelerate the compilition time from hours to minutes with following trick
all cpps have become this first line
#include "all.h"
#pragma hdrstop
default was an include of "vcl.h"
"all.h" will includes all header, wich are needed in all! units. every unit will skip all sources, wich depend on header before pragma hdrstop.
Example:
Unit1.h
#include <string>
Unit1.cpp
#include "all.h"
#pragma hdrstop
#include "Unit1.h"
Unit2.h
#include <vcl>
Unit2.cpp
#include "all.h"
#pragma hdrstop
#include "Unit2.h"
all.h
#include <string>
#include <vcl>
Importing
dont use all.h in headerfiles
you can add all includes, wich are used in the project header, like ,
All sources wich depend on the "pre compiled headers" will not be compiled again!
generation of precompiled headers will be slow! So only add headers in all.h, which will not be changed often. Like system headers or your headers wich are already finished.
compilation can be failed. sometimes the order of the includes produce an "deadlock" for the comilation. if its happen, deactivate "pre-compiled headers". Most problems will be solved, if you write your c++ like in java: every class will become his own files(cpp and h).
Filename in the project option "Pre-Compiled headers" shows the basename of the real precompiled files. an unit can share an precompiled file with another unit, if it have (exact) the same inludes before "pragma hdrstop". Best performance is reached, if you have only one file with an numeric postfix. Example for more than one precompiled header:
Unit1.h
#include <string>
Unit1.cpp
#include "all.h"
#pragma hdrstop
#include "Unit1.h"
Unit2.h
#include <vcl>
Unit2.cpp
#include <vcl> //!!!!!!!!!!!!!!!!!!! produce a second version of an precompiled file
#pragma hdrstop
#include "Unit2.h"
all.h
#include <string>
#include <vcl>
Make sure you are using the "make" command and not the "build" command, unless it is required.
Making a project with the Borland tools has always seemed to have that issue -- that it doesn't necessarily notice which ones have changed and starts to compile everything.
Look at the Pre-Compiled Headers options, which may help speed things up.
When Borland/CodeGear, starting in C++Builder 2007, switched to the MSBuild system, the compilations have gone much faster and are more efficient.