In VS2010 which functions are exported into a DLL? - visual-studio-2010

I am building a DLL to wrap a C/C++ library to be called from matlab.
I am using the standard __declspec(dllexport) to export functions. Specifically, I have several .h files with code that essentially looks like:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _MSC_VER
__declspec(dllexport)
#endif
void FOO();
#ifdef __cplusplus
}
#endif
Then, I have a lib.h file, that just includes all these .h files.
#include "foo.h"
#include "bar.h"
My project configuration is such that it does build a DLL, but the mystery is that BAR() is in the DLL (as verified by dumpbin) but FOO is not.
Any ideas on how this could possibly be the case?

In the example above, the problem was due to the fact that BAR did not have a definition in the source tree of the project.
I'm relatively new to TFS and VS, so let me see if I can explain this in a way that makes sense.
The solution has multiple projects. One project is called MatlabDLL, the main project is called OurLibrary. The Matlab DLL is not importing all of Library, just wraps parts of it for inclusion into Matlab. In many cases, Matlab DLL can easily call directly to the C functions, in other cases, functions have to be rewritten to handle Matlab C/DLL calling semantics.
So, BAR had to have a Matlab specific C wrapper around it to enable it to be called from Matlab. The associated source file bar.cpp was in the MatlabDLL project. (Under the hood, BAR calls a number of functions whose source lives in the OurLibrary project, none of whose source files are in the MatlabDLL project.)
FOO had an implementation that did not require a C specific wrapper, so foo.cpp lived in the OurLibrary part of the source tree, and had no source files in the MatlabDLL project, although it's associated .h file was referenced by MatlabDLL.h.
In the end, VS2010 appears to only build the __declspec(dllexport)'d functions that have associated c files in the project. Adding foo.c to the project fixed the problem.

Related

ESP32 compiler giving "multiple definition of" errors

Got a new issue I've not come across before that's appeared when using the Espressif ESP32 ESP-IDF standard setup under VSCode. It uses the GNU compiler.
I'm getting "multiple definition of" errors on variables that share the same name, but which should be local.
So I use a .c and .h pair of files approach.
In my .c files I do this at the top
#define IO_EXPANDER_C //<<<This is a unique define for this file pair
#include "io-pca9539.h"
In my .h files I do this:
#ifdef IO_EXPANDER_C
//----- INTERNAL ONLY MEMORY DEFINITIONS -----
uint8_t *NextReadDataPointer;
//----- INTERNAL & EXTERNAL MEMORY DEFINITIONS -----
//(Also defined below as extern)
int SomeVariableIWantAvailableGlobally;
#else
//----- EXTERNAL MEMORY DEFINITIONS -----
extern int SomeVariableIWantAvailableGlobally;
#endif
It's a great simple system, any other .c file that includes the .h file (without the #define above its include statemnt), gets all of its extern variables, none of its local variables.
But, compiling in VSCode with my ESP-IDF based project, I'm getting "multiple definition of" errors relating to "NextReadDataPointer"
I use the same variable name NextReadDataPointer in another file pair in just the same way, but it's never declared anywhere as extern and each file pair uses a separate #define (IO_EXPANDER_C and LED_C). I do this all the time normally and I can't see any obvious mistakes.
I've never seen a C compiler do this before, it's as if it's mixing up the local definitions somehow. A #define should only have scope in the file it is declared in and in any includes within that file.
Even odder, the error is not generated if the project is built but a function is called from just one of the file pairs that share the same local variable name. It's only generated when functions are called from both file pairs from my main application.
Can anyone shed light on whether the GNU C compiler does something funky for a standard ESP-IDF project as it's got me baffled?
uint8_t *NextReadDataPointer; creates a variable which is visible across all translation units, i.e. it's the opposite of "private". If you include this header in multiple c files and the linker tries to link those together; it'll see a conflict. The keyword you're looking for is static, for example static uint8_t *NextReadDataPointer; creates a variable that is not visible across translation units. The reason you don't see the problem if calling a function from only one of those two files is because in this case the linker doesn't bother looking into the other one.
Personally I'd avoid such clever preprocessor hacks because it's quite difficult to see how files include one another and debug the resulting problems. I'd suggest sticking to the standard way of declaring shared things in header files and keeping the private stuff inside the c file (prepended by static).

Replacing MSVC CRT function with private implementation

I have an embedded IoT project that I like to first develop in part by using PC tools such as VisualStudio. My embedded project has only a flash memory for a file system, and I'd like to redirect fopen fread etc. to my own private implementation on Windows. But what I'm encountering is an inability to have my private CRT library take precedence over the built-in CRT (e.g., built-in behavior driven by /MD compiler switch).
I have a simple three project solution.
Project 1 is a test executable. It has a one line main:
int main()
{
test();
}
Project 2 and 3 are static libraries. Project 2 has:
#include <string.h>
#include <stdio.h>
void test()
{
printf("%s\n", strchr("x", 'x'));
}
Project 3 has:
char * strchr(const char * s, int c) // exact signature of MSVC
{
return "overridden";
}
I expect output to be overridden but instead it is
x
But if I add this to Project 1:
printf("%s\n", strchr("y", 'y'));
The output will be
overridden
overridden
First one from test() in library, second from executable main() directly.
Any suggestions?
The linker resolves symbols on a first match basis - priority to separately linked .obj files, then .lib files in the order presented to the linker of the command line. So you can normally override a library symbol just be linking your own replacement. I have never tried it with MSVC, and it is a somewhat brutal approach.
An alternative solution that does not rely on specific linker behaviour is to use the pre-processor to replace standard symbols with your own alternatives. For example:
#if defined _WIN32
#define fopen test_fopen
FILE* test_fopen( const char * filename, const char * mode ) ;
#endif
add the other macros and declarations you need in a header file called testlib.h for example then use a "forced include" (/FI testlib.h in MSVC) to invisibly include the test interface everywhere. Then when built on Windows, all fopen calls will be replaced with test_fopen calling your replacement functions instead.
If the problem is caused by CRT usage in a static library only, and linker is finding MSVCRT DLL export lib before it finds private CRT static lib, a workaround might be to force a reference to the private CRT in the executable source files.
Example matching code above, placed in main as a global:
static char * (*p_strchr)(const char *, int) = strchr;
It is less than ideal but it alters linker search order in a reliable way.
More findings
There may be combinations (that I don't totally understand) where the linker will emit a LNK1169 "one or more multiply defined symbols" (more than one definition) linker error. For example, it might say fopen is defined more than once, and if you reverse the order of the private and MS libraries on the command line, then it might say fread is defined more than once. Perhaps it is caused by MSVC lib having DLL export signature, and the private lib being an import symbol. The behavior is hard to determine as it doesn't error on all of the functions that are being overridden.
If it is possible to switch all private libraries to /MT compiler switch (use static CRT), then the LNK1169 problem is resolved.

g++ library not found but not for gcc

I want to use my school custom library in a C++ project but the library linking seems not working... When I create my program in C and I try to compile it, it work...
See by yourself:
I think that the X11 and/or Xext libraries dependencies of the Mlx are in cause, there can be some
#if __cplusplus
void *x11_mlx_function_wanted(void);
#endif
I had already check if the mlx contains some check like that and I saw nothing.
Thank you in advance
EDIT
And I succeed in objective-c.
The problem is C++ name-mangling. If you declare a function in C11, it ends up with a "mangled" name, which encodes the namespace and the types of the arguments. That's necessary because in C++, various overloads can exist for the same function name. The overloads are independent functions; they do not even have to be in the same object library.
In the object library itself, the functions will have ordinary C names. But since the header file is processed with a C++ compiler, the declared functions will be named as though they were C++ functions.
One possible solution might be to declare all the included functions to be C functions:
extern "C" {
#include "/usr/X11/include/mlx.h"
}

Using CUDA and Armadillo

I have a .cu file in a 64x VS2010 project. This project is configured to extract a .mexw64 file. Bellow there is the example I run. Inside the mex function I want to use some functions of the Armadillo linear algebra library. So When the #include "armaMex.hpp" is used the compiler return some errors:
error C3203: 'fixed' : unspecialized class template can't be used as a template argument for template parameter 'T1', expected a real type c:....\armadillo-4.200.0\include\armadillo_bits\Mat_meat.hpp
error C2955: 'arma::Mat::fixed' : use of class template requires template argument list c:\ ....\armadillo-4.200.0\include\armadillo_bits\Mat_meat.hpp
error C1903: unable to recover from previous error(s); stopping compilation c:\ ....\armadillo-4.200.0\include\armadillo_bits\Mat_meat.hpp
I can not figure out what is causing these errors. Could you please give an explanation?
#include "mex.h"
#include "armaMex.hpp"
void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mexPrintf("hello!\n");
}
PS: CUDA SDK 5.5 64x, VS2010
This is a known limitation of nvcc (technically cudafe++, I think). nvcc uses file extension to determine whether a given source file should be processed for device code or passed to the CUDA preprocessors and then the device compiler. It looks like that compilation trajectory can't correctly parse some of the very complex declarations that Armadillo contains, and the compile fails. This is known to happen with Boost, Eigen and QT. I guess Armadillo is in the same boat.
The solution is to not import Armadillo headers inside a .cu file. Put your host boost code in a .cc file, device code and kernel launches in a separate .cu file and make some thin wrappers to access the kernel calls from the .cc file. You can still pass all the source to nvcc to compile into a single object file, but separating the Armadillo imports from the device code eliminates the problem of the front end choking on the complex template declarations Armadillo contains.

Creating a DLL, confusion with __declspec(dllexport)

Visual Studio C++ 2005
Windows XP
I am creating this DLL library. The DLL actually links with another LIB. I have included the headers and lib path. Everything compiles ok.
Actually, this code I wrote for running on linux, which runs ok. Now I am porting it to run on windows.
However, I have noticed that some DLL from some code samples use this in there header file:
static __declspec(dllexport) float some_function(int num1, int num2);
However, I have done the following, sample code below for the header *.h file. However, not sure if I still need the above or not?
#ifdef __cplusplus
extern "C" {
#endif
media_t* get_media(media_description_t* obj);
void* get_item(media_description_list_t *obj, int num);
int get_number_format(media_t *obj);
const char* get_media_value(media_t *obj);
#ifdef __cplusplus
}
#endif
Sample code for for implementation *.cpp file
int get_number_format(media_t *obj)
{
Media *med = (Media*)obj;
return med->getNumFormat();
}
So, do I need this static __declspec(dllexport)?
Many thanks for any advice,
The linker needs to be told which of your functions should be exported, making them usable by other code that uses your DLL. __declspec(dllexport) does this. But you can also do it by providing the linker with a .def file, a list of exported function names. Somewhat painful because it now is up to you to keep that file in sync with your code. Docs are here.
__declspec(dllexport) adds the function to the DLL's export table. This table is a convention that allows a process wishing to use the DLL to correctly call the function.
There are other ways to export functions from DLLs, but this one is probably the more modern and easier to use.
yes it is needed, if you don't have the dllexport the function will not be accessible in any other application where you are calling that function.
If you put the implementation of a method in the h file, you don't need to use the __declspec(dllexport) declaration.

Resources