Skip to content

Instantly share code, notes, and snippets.

@tmpvar
Created February 26, 2021 04:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmpvar/668006ffe569bfcce99d93e2d75fae48 to your computer and use it in GitHub Desktop.
Save tmpvar/668006ffe569bfcce99d93e2d75fae48 to your computer and use it in GitHub Desktop.
c bidirectional linkage (exe <-> dll)
cmake_minimum_required(VERSION 3.17)
project(bidirectional-link)
add_executable(main main.c)
set_property(TARGET main PROPERTY ENABLE_EXPORTS 1)
add_library(loadable SHARED loadable.c)
target_link_libraries(loadable main)
#include <stdio.h>
#include "main.h"
__declspec(dllexport) void loadable_setup() {
printf("loadable_main, calling hello_main..\n");
hello_main();
printf("done!\n");
}
#include <windows.h>
#include <stdio.h>
#include "main.h"
typedef void (__cdecl *loadable_setup)();
typedef struct loadable_t {
loadable_setup setup;
HINSTANCE hinstLib;
} loadable_t;
void hello_main() {
printf("main says hello\n");
}
#ifdef _WIN32
loadable_t load(const char* path) {
loadable_t ret = {
.hinstLib = LoadLibrary(TEXT(path)),
.setup = NULL
};
if (ret.hinstLib) {
ret.setup = (loadable_setup)GetProcAddress(ret.hinstLib, "loadable_setup");
}
return ret;
}
void unload(loadable_t *loadable) {
if (loadable->hinstLib) {
FreeLibrary(loadable->hinstLib);
loadable->hinstLib = NULL;
loadable->setup = NULL;
}
}
#endif
void main() {
printf("main::main!\n");
loadable_t loadable = load("loadable.dll");
loadable.setup();
loadable.setup();
loadable.setup();
loadable.setup();
loadable.setup();
unload(&loadable);
}
#pragma once
__declspec(dllexport) void hello_main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment