Это не требует усложнения вашего кода (во всяком случае, за исключением обычного экспорта функций из DLL в целом).
Я подозреваю, что ваша текущая проблема в основном связана со средой сборки, но давайте вкратце рассмотрим.Пример рабочего (проверенного) кода для того, что вы пытаетесь сделать.
Вот код для супер-простого исполняемого файла с экспортированной функцией:
#include <stdio.h>
#include <conio.h>
extern "C" {
void __declspec(dllexport) foo() {
printf("in foo\n");
}
}
int main() {
getch();
}
Обратите внимание, чтодля этого требуется main
, чтобы он служил в качестве точки входа, даже если он не будет (по крайней мере, обычно) вызываться.Конечно, вместо этого он может иметь WinMain
в качестве точки входа - в любом случае, он фактически не будет использоваться.Нам просто нужно что-то, чтобы удовлетворить компоновщик, чтобы он создавал исполняемый файл.
... и вот заголовок, который объявляет свою экспортированную функцию, чтобы что-то еще (наша DLL) могло использовать его:
#pragma once
extern "C" {
void __declspec(dllimport) foo();
}
Мы можем построить исполняемый файл довольно нормально, за исключением того, что мы должны убедиться, что он использует стандартную библиотеку в DLL (иначе ее стандартная библиотека не будет правильно инициализирована, поэтому она не будет работать): cl /MD trash9.cpp
Тогда у нас есть код для DLL
#include "trash9.h"
#include <iostream>
extern "C" {
void __declspec(dllexport) bar() {
printf("in bar\n");
foo();
printf("back in bar\n");
}
}
void DllMain() {}
... и вот его заголовок:
#pragma once
extern "C" {
void __declspec(dllimport) bar();
}
DLL также должна использовать стандартную библиотеку вDLL, поэтому мы строим это примерно так: cl /MD /LD trash8.cpp trash9.lib
./MD
означает, что он должен использовать стандартную библиотеку в DLL, а /LD
означает, что это должно создать исполняемый файл (вместо исполняемого, как это было бы по умолчанию).
Наконец, вот исполняемый файлкоторый использует bar
:
#include "trash8.h"
int main() {
bar();
}
Мы можем построить это так: cl /MD use_bar.cpp trash8.lib
.
Когда мы запустим его, мы получим примерно то, что вы ожидаете:
in bar
in foo
back in bar
Это оставляет только одно препятствие: заставить Visual Studio согласиться делать то, что вы хотите.Моя непосредственная реакция заключается в том, что первое, что нужно сделать, - это поместить исполняемый файл в один проект, DLL во второй проект и (если вы имеете дело) исполняемый файл, который использует DLL в третьем проекте, со ссылкой извторой к первому и от третьего ко второму.