I am struggling to understand if I can prevent exposing certain function calls from within a DLL that I am building. The function calls I want to hide are calls that are exposed by sqlite3.dll which I am building into another DLL of my own making. sqlite3.dll exposes 5 functions, one of which looks like this in the header:
SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*);
The macros at play here are defined earlier as:
/*
** Provide the ability to override linkage features of the interface.
*/
#ifndef SQLITE_EXTERN
# define SQLITE_EXTERN extern
#endif
#ifndef SQLITE_API
# define SQLITE_API
#endif
#ifndef SQLITE_CDECL
# define SQLITE_CDECL
#endif
#ifndef SQLITE_STDCALL
# define SQLITE_STDCALL
#endif
Now, I am building sqlite3.dll into my application by linking against sqlite3.lib and including sqlite3.h (the source of the prior code snippets).
I realize I may be able to play with those macros to achieve what I want.
I expose the functions in my own dll with:
/* module entry point */
int __declspec(dllexport) __stdcall load_properties(CAObjHandle context);
When I look at the functions available in the output of my build, I get my functions+5 functions from the sqlite library. All of the functions in sqlite that are exposed have the declaration structure similar to what I showed for close() above.
Is there a way I can hide the sqlite functions? Is it the .lib file that is causing the issue? That file was auto-generated so I am not sure what is in there.
I discovered the answer. The sqlite3.dll was incorrectly specified as a source of exports to the compiler. Removing the directive to export functions from sqlite3.dll corrected the issue.
Related
I'm studying the SQLite source code (in c), but there are some things I can't figure out what they are, and I hope you can give me a hand.
I know c, c++ and JAVA basics but I have never seen something like this and I don't know how to search for it.
In a c file, there are the next definitions (among others):
#ifndef SQLITE_CDECL
# define SQLITE_CDECL
#endif
#ifndef SQLITE_API
# define SQLITE_API
#endif
And then the above definitions are used like this:
SQLITE_API int SQLITE_CDECL sqlite3_conf(int, ...){
//code
I know "SQLITE_API" and "SQLITE_CDECL" are not the return types, function names, keywords, K&R style nor variable modificators...
Why are this words placed like that in the function? What are they for?
They're used to modify the attributes of the functions on different platforms or when building certain ways. Most of the time there may be no need for them, but in certain situations they may be useful, e.g. using __declspec(dllexport) when building a DLL or using static when including the file directly instead of having the linker perform linkage between the object files.
These two declarations look like they exist so that they can be defined differently to support certain quirks of development on Windows. Note that on the #define lines, they aren't defined to any value. This means that they will be replaced with nothing that the parser sees. So, SQLITE_API int SQLITE_CDECL sqlite3_conf(int, ...){ will end up being reduced to int sqlite3_conf(int, ...){ after the preprocessor runs. On Windows, they can be defined differently to support building DLLs with __declspec (see https://msdn.microsoft.com/en-us/library/dabb5z75.aspx) and specifying calling conventions (see https://msdn.microsoft.com/en-us/library/zkwh89ks.aspx).
I recently had to face a fairly complex issue regarding lib management, but I would be very surprised to be the first one.
Let's imagine you are creating a library (static or dynamic) called lib1 in C. Inside lib1 are a few functions that are exposed through an API, and a few other ones which remain private.
Ideally, the private functions would be static. Unfortunately, let's assume one of the source files, called extmod.c, come from another project, and it would be beneficial to keep it unmodified. Therefore, it becomes unpractical to static the functions it defines.
As a consequence, all the functions defined into extmod are present into lib1 ABI, but not the API, since the relevant *.h is not shipped. So no one notice.
Unfortunately, at later stage, someone wants to link both lib1 and another lib2 which also includes extmod. It results in a linking error, due to duplicate definitions.
In C++, the answer to this problem would be a simple namespace. In C, we are less lucky.
There are a few solutions to this problem, but I would like to probe if anyone believes to have found an efficient and non-invasive way. By "non-invasive", I mean a method which avoids if possible to modify extmod.c.
Among the possible workaround, there is the possibility to change all definitions from extmod.c using a different prefix, effectively emulating namespace. Or the possibility to put the content of extmod.c into extmod.h and static everything. Both method do extensively modify extmod though ...
Note that I've looked at this previous answer, but it doesn't address this specific concern.
You could implement your 'different prefix' solution by excluding extmod.c from your your build and instead treating it as header file in a way. Use the C pre-processor to effectively modify the file without actually modifying it. For example if extmod.c contains:
void print_hello()
{
printf("hello!");
}
Exclude this file from your build and add one called ns_extmod.c. The content of this file should look like this:
#define print_hello ns_print_hello
#include "extmod.c"
On compilation, print_hello will be renamed to ns_print_hello by the C pre-processor but the original file will remain intact.
Alternatively, IF AND ONLY IF the function are not called internally by extmod.c, it might work to use the preprocessor to make them static in the same way:
#define print_hello static print_hello
#include "extmod.c"
This should work for you assuming you have control over the build process.
One way you can do prefixing without actually editing extmod.c is as follows:
Create a new header file extmod_prefix.h as:
#ifndef EXTMOD_PREFIX_H
#define EXTMOD_PREFIX_H
#ifdef LIB1
#define PREFIX lib1_
#else
#ifdef LIB2
#define PREFIX lib2_
#endif
#endif
#define function_in_extmod PREFIX##function_in_extmod
/* Do this for all the functions in extmod.c */
#endif
Include this file in extmod.h and define LIB1 in lib1's build process and LIB2 in lib2.
This way, all the functions in extmod.c will be prefixed by lib1_ in lib1 and lib2_ in lib2.
Here's the answer (in the form of a question). The relevant portion:
objcopy --prefix-symbols allows me to prefix all symbols exported by
an object file / static library.
I am trying to think of the most elegant solution for a C program I am currently writing. Basically, I have a small core program and then lots of additional "modules" which can be called by the core program and contain most of the functionality. The idea is that the core and and each of these modules is independent.
The inclusion of these modules is determined at compile time and once I register them then the core has function pointers to the modules which it can then use.... but what is the best way of making these modules known in the first place for registration with minimal dependencies? I am currently using a "module factory" type approach, which knows about the modules and is called by the core to obtain their details for registration. But I was wondering if, through make and the preprocessor if there might be a better way of "auto-discovering" which modules have been compiled in with the core?
In the past I have used dynamically loaded libraries but in this case my modules need to be compiled in so dynamically loading a bunch of libraries from a directory and solving it that way is not an option.
I'm not quite sure if I understand the question, but I suppose you could as always create something semi-obscure with macros. I wouldn't really recommend it, but for what it is worth...:
Suppose you have one module called "module_this" and another called "module_that". There's also "module_missing" which isn't compiled with the program.
You could then create something like:
module_this.h
#ifndef MODULE_THIS // your ordinary header guard
#define MODULE_THIS module_this, // add a function name plus a comma
void module_this (void);
#endif
module_that.h
#ifndef MODULE_THAT // your ordinary header guard
#define MODULE_THAT module_that, // add a function name plus a comma
void module_that (void);
#endif
core.c
#include "something that includes all linked files.h" // generate this externally
#ifndef MODULE_THIS // this module is compiled
#define MODULE_THIS // so it wont get defined here
#endif
#ifndef MODULE_MISSING // module that was not compiled
#define MODULE_MISSING // will get defined as empty macro
#endif
#ifndef MODULE_THAT // this module is compiled
#define MODULE_THAT // so it wont get defined here
#endif
typedef void(*module_t)(void); // your function pointer type to use
static const module_t MODULE_TABLE [] = // list of all existing modules
{
MODULE_THIS // note absence of commas
MODULE_MISSING
MODULE_THAT
};
#define MODULES_N ( sizeof(MODULE_TABLE) / sizeof(module_t) )
...
printf("There are %d modules in the project.", MODULES_N);
This relies on a header file which is created from scripts/the make file, containing a number of #include.
For example I have a can.h header file that contains
#ifdef MC
extern int speed;
// many more variables and function prototypes
#endif
EDIT: I would want an option for the user to define MC that enables such variable and function prototypes. It is to be defined in C main alongside include directives (e.g. #define MC) however, other header files cannot link to main.c. Instead, i ended up defining such macros in can.h header itself. All i can think is writing a main.h too where can.h will include main.h. are there other ways to go around this problem?
It's not entirely clear to me what you are trying to do, but perhaps you want this:
/* in file can.h */
extern int speed;
and then
/* in file main.c */
#include "can.h"
int speed;
The header can.h just declares the existence of speed so that other modules can refer to it as an external symbol. The storage for this object is then allocated in main.c, when you write the the definition of speed.
You can either create a configuration header that has all the macros that you want defined and #include it in every header, or you can define configuration macros on the command line.
Use #include - Then you get those bits that you require
Inclusion is simply file content insertion by the preprocessor, anything declared or defined prior to inclusion will be defined in the include file. So:
#define MC
#include "can.h"
While that achieves what you have asked, I would not necessarily recommend it however, and might question the design.
You can have such macro added at your project level.
Such macro are also known as Preprocessor definitions. Visual studio provides such definition in project settings/configurations..
So you can have it added there and compile the solution for including mentioned declarations or remove it if you don't want to include it.
Adding the screen shot.
#ifndef _DLL_TUTORIAL_H_
#define _DLL_TUTORIAL_H_
#include <iostream>
#if defined DLL_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif
extern "C"
{
DECLDIR int Add( int a, int b );
DECLDIR void Function( void );
}
#endif
What does the code DECLDIR __declspec(dllexport) really do?
In the Microsoft world, __declspec(dllexport) makes a function or class callable from outside the DLL.
When you create a DLL, by default, any functions defined within the DLL are only callable from that same DLL. You cannot call that function from an executable or a different DLL.
If you want your a function to be called from outside the DLL, you need to export it by adding __declspec(dllexport).
One way to think about it is that __declspec(dllexport) marks a function as being part of a DLL's public interface.
While you didn't ask about __declspec(dllimport) that is sort of the opposite. When calling a function in a different DLL, your DLL needs to know that it's part of a different DLL's public interface so it can properly handle the call (calling a function in a different DLL requires more complex code that calling a function in yourself).
It defines the DECLDIR macro constant to be __declspec(dllexport). dllexport is for exporting functions from DLLs. Here's a quote from this page:
These attributes explicitly define the
DLL's interface to its client, which
can be the executable file or another
DLL. Declaring functions as dllexport
eliminates the need for a
module-definition (.DEF) file, at
least with respect to the
specification of exported functions.
Note that dllexport replaces the
__export keyword.
If a class is marked
declspec(dllexport), any
specializations of class templates in
the class hierarchy are implicitly
marked as declspec(dllexport). This
means templates are explicitly
instantiated and its members must be
defined.
__declspec, by the way, is explained here.