./CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
include(GenerateExportHeader)
project(MyDLL)
set(LIB_SRCS dllmain.cpp)
SET (LIB_TYPE SHARED)
add_library(MyDLL ${LIB_TYPE} ${LIB_SRCS})
GENERATE_EXPORT_HEADER(MyDLL)
ENABLE_TESTING()
ADD_SUBDIRECTORY(tests)
./dllmain.cpp
#include <windows.h>
#include <iostream>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
extern "C" __declspec(dllexport) int foo()
{
return 1;
}
./tests/CMakeLists.txt
link_directories (${CMAKE_CURRENT_BINARY_DIR}/../)
include_directories (${CMAKE_CURRENT_BINARY_DIR}/../)
ADD_EXECUTABLE(test1 test1.cpp)
ADD_TEST(NAME mytest COMMAND test1)
target_link_libraries(test1 MyDLL.dll)
./tests/test1.cpp
#include <windows.h>
#include <iostream>
#include <mydll_export.h>
extern "C" __declspec(dllimport) int foo();
int main(int, char**)
{
std::cout << foo() << std::endl;
}
NOTE: The exported function symobls need to be lower case to work with the dllimport/dllexport
macros! Otherwise you will get a undefined reference to __imp_foo
linker error.
Compile, debug and test:
mkdir debug; cd debug; rm CMakeCache.txt; cmake .. -DCMAKE_BUILD_TYPE=Debug "-GMinGW Makefiles"
mingw32-make.exe
& "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe" /DebugExe ".\tests\test1.exe"
Compile for release and import:
mkdir release; cd release; rm CMakeCache.txt; cmake .. -DCMAKE_BUILD_TYPE=Release "-GMinGW Makefiles"
mingw32-make.exe
In e.g. Microsoft Access 2019, create a module or add at the top of an existing one for the functions to be available in MS Access SQL. I failed to call the function directly in MS Access SQL, but it was possible to call a VBA wrapper function.
Option Compare Database
Public Declare PtrSafe Function foo _
Lib "libMyDLL" Alias "foo" _
(ByVal strOne As String, ByVal strTwo As String) As Double
Function fooWrapper()
fooWrapper = foo()
End Function
Now you can use the function in an SQL query like this:
"SELECT * FROM mytable ORDER BY fooWrapper() ASC"