如何使用C++导出制作动态链接库
How to make Dynamic-Link Library with exports with C++
我正在Visual Studio 2019中构建一个DLL项目。
我将写入的数组库转换为 DLL,但它不起作用。
有两个编译错误:
C2254:假设函数被定义了两次。
C2953:假设数组类已被声明。
通过在数组类声明中定义函数的同时定义函数来修复 C2254 错误。所以代码是:
//ArrayLib.h
#ifdef ARRAYLIB_EXPORTS
#define ARRAYLIB_API __declspec(dllexport)
#else
#define ARRAYLIB_API __declspec(dllimport)
#endif
typedef signed long int Long;
template <typename T>
class Array {
public:
Array(Long capacity = 256) {
this->front = new T[capacity];
this->capacity = capacity;
this->length = 0;
}
Array(const Array& source) {
this->front = new T[source.capacity];
this->capacity = source.capacity;
Long i = 0;
while (i < source.length) {
this->front[i] = source.front[i];
i++;
}
this->length = source.length;
}
~Array() {
if (this->front != 0) {
delete[] this->front;
}
}
Long Store(Long index, T object) {
this->front[index] = object;
this->length++;
return index;
}
Long Insert(Long index, T object) {
T(*objects);
Long i;
Long j = 0;
objects = new T[this->capacity + 1];
i = 0;
while (i < index) {
objects[j] = this->front[i];
j++;
i++;
}
j++;
while (i < this->length) {
objects[j] = this->front[i];
j++;
i++;
}
if (this->front != 0) {
delete[] this->front;
}
this->front = objects;
this->capacity++;
this->front[index] = object;
this->length++;
return index;
}
Long AppendFromFront(T object) {
Long index = 0;
T(*objects);
Long i = 0;
objects = new T[this->capacity + 1];
while (i < this->length) {
objects[i + 1] = this->front[i];
i++;
}
if (this->front != 0) {
delete[] this->front;
}
this->front = objects;
this->capacity++;
this->front[index] = object;
this->length++;
return index;
}
Long AppendFromRear(T object) {
Long index;
T(*objects);
Long i = 0;
objects = new T[this->capacity + 1];
while (i < this->length) {
objects[i] = this->front[i];
i++;
}
if (this->front != 0) {
delete[] this->front;
}
this->front = objects;
this->capacity++;
index = this->capacity - 1;
this->front[index] = object;
this->length++;
return index;
}
Long Delete(Long index) {
T(*objects) = 0;
Long i = 0;
if (this->capacity > 1) {
objects = new T[this->capacity - 1];
}
while (i < index) {
objects[i] = this->front[i];
i++;
}
i = index + 1;
while (i < this->length) {
objects[i - 1] = this->front[i];
i++;
}
if (this->front != 0) {
delete[] this->front;
this->front = 0;
}
if (this->capacity > 1) {
this->front = objects;
}
this->capacity--;
this->length--;
index = -1;
return index;
}
Long DeleteFromFront() {
T(*objects) = 0;
Long i = 1;
if (this->capacity > 1) {
objects = new T[this->capacity - 1];
}
while (i < this->length) {
objects[i - 1] = this->front[i];
i++;
}
if (this->front != 0) {
delete[] this->front;
this->front = 0;
}
if (this->capacity > 1) {
this->front = objects;
}
this->capacity--;
this->length--;
return -1;
}
Long DeleteFromRear() {
T(*objects) = 0;
Long i = 0;
if (this->capacity > 1)
{
objects = new T[this->capacity - 1];
}
while (i < this->length - 1)
{
objects[i] = this->front[i];
i++;
}
if (this->capacity > 1)
{
this->front = objects;
}
this->capacity--;
this->length--;
return -1;
}
void Clear() {
if (this->front != 0)
{
delete[] this->front;
this->front = 0;
}
this->capacity = 0;
this->length = 0;
}
Long Modify(Long index, T object) {
this->front[index] = object;
return index;
}
Long LinearSearchUnique(void *key, int(*compare)(void*, void*)) {
Long index = -1;
Long i = 0;
while (i < this->length && compare(this->front + i, key) != 0)
{
i++;
}
if (i < this->length)
{
index = i;
}
return index;
}
void LinearSearchDuplicate(void *key, Long* (*indexes), Long *count, int(*compare)(void*, void*)) {
Long i = 0;
Long j = 0;
*count = 0;
*indexes = new Long[this->length];
while (i < this->length)
{
if (compare(this->front + i, key) == 0)
{
(*indexes)[j] = i;
j++;
(*count)++;
}
i++;
}
}
Long BinarySearchUnique(void *key, int(*compare)(void*, void*)) {
Long index = -1;
Long first = 0;
Long last;
Long mid;
last = this->length - 1;
mid = (first + last) / 2;
while (first <= last && compare(this->front + mid, key) != 0)
{
if (compare(this->front + mid, key) < 0)
{
first = mid + 1;
}
else
{
last = mid - 1;
}
mid = (first + last) / 2;
}
if (first <= last)
{
index = mid;
}
return index;
}
void BinarySearchDuplicate(void *key, Long* (*indexes), Long *count, int(*compare)(void*, void*)) {
Long first = 0;
Long last;
Long mid;
Long i;
Long j = 0;
*count = 0;
*indexes = new Long[this->length];
last = this->length - 1;
mid = (first + last) / 2;
while (first <= last && compare(this->front + mid, key) != 0) {
if (compare(this->front + mid, key) < 0) {
first = mid + 1;
}
else {
last = mid - 1;
}
mid = (first + last) / 2;
}
i = mid - 1;
while (i >= first && compare(this->front + i, key) == 0) {
i--;
}
first = i + 1;
i = first;
while (i <= last && compare(this->front + i, key) == 0) {
(*indexes)[j] = i;
j++;
(*count)++;
i++;
}
}
void BubbleSort(int(*compare)(void*, void*)) {
Long i = 0;
Long j;
T temp;
Long check = 1;
while (i < this->length - 1 && check == 1) {
check = 0;
j = 0;
while (j < this->length - i - 1) {
if (compare(this->front + j, this->front + (j + 1)) > 0) {
temp = this->front[j];
this->front[j] = this->front[j + 1];
this->front[j + 1] = temp;
check = 1;
}
j++;
}
i++;
}
}
void SelectionSort(int(*compare)(void*, void*)) {
Long i = 0;
Long j;
T min;
Long minIndex;
while (i < this->length - 1) {
minIndex = i;
min = this->front[minIndex];
j = i + 1;
while (j < this->length) {
if (compare(&min, this->front + j) > 0) {
minIndex = j;
min = this->front[minIndex];
}
j++;
}
this->front[minIndex] = this->front[i];
this->front[i] = min;
i++;
}
}
void InsertionSort(int(*compare)(void*, void*)) {
Long i = 1;
Long j;
T temp;
while (i < this->length) {
temp = this->front[i];
j = i - 1;
while (j >= 0 && compare(this->front + j, &temp) > 0) {
this->front[j + 1] = this->front[j];
j--;
}
this->front[j + 1] = temp;
i++;
}
}
void Merge(const Array& one, const Array& other, int(*compare)(void*, void*)) {
Long i = 0;
Long j = 0;
Long k = 0;
if (this->front != 0) {
delete[] this->front;
}
this->front = new T[one.length + other.length];
this->capacity = one.length + other.length;
this->length = 0;
while (i < one.length && j < other.length) {
if (compare(one.front + i, other.front + j) < 0) {
this->front[k] = one.front[i];
k++;
this->length++;
i++;
}
else {
this->front[k] = other.front[j];
k++;
this->length++;
j++;
}
}
while (i < one.length) {
this->front[k] = one.front[i];
k++;
this->length++;
i++;
}
while (j < other.length) {
this->front[k] = other.front[j];
k++;
this->length++;
j++;
}
}
T& GetAt(Long index) {
return this->front[index];
}
T& operator [](Long index) {
return this->front[index];
}
T* operator +(Long index) {
return (this->front + index);
}
Array& operator =(const Array& source) {
if (this->front != 0) {
delete[] this->front;
}
this->front = new T[source.capacity];
this->capacity = source.capacity;
Long i = 0;
while (i < source.length) {
this->front[i] = source.front[i];
i++;
}
this->length = source.length;
return *this;
}
// 20160512 추가
void Swap(Long toIndex, Long fromIndex) {
T object = this->front[fromIndex];
Long count;
if (fromIndex > toIndex) {
count = fromIndex - toIndex;
memmove(this->front + toIndex + 1, this->front + toIndex, sizeof(T) * count);
}
else {
count = toIndex - fromIndex;
memmove(this->front + fromIndex, this->front + fromIndex + 1, sizeof(T) * count);
}
this->front[toIndex] = object;
}
Long GetCapacity() const {
return this->capacity;
}
Long GetLength() const {
return this->length;
}
private:
T(*front);
Long capacity;
Long length;
};
extern ARRAYLIB_API int nArrayLib;
ARRAYLIB_API int fnArrayLib(void);
这是 cpp 文件:
#include "ArrayLib.h"
ARRAYLIB_API int nArrayLib=0;
ARRAYLIB_API int fnArrayLib(void)
{
return 0;
}
但是,我不确定如何解决C2953错误。
有办法吗?
还是我又犯了一个错误?
我是第一次构建 DLL。
我甚至不知道为什么nArrayLib和fnArrayLib存在。
更让我困惑的是,在简单的控制台应用程序或使用 GUI 构建器创建的应用程序中没有发生错误。
上述错误发生在使用 MFC 的记事本应用程序中。
感谢您的帮助。
一个不完美但有效的方法是在声明模板后显式实例化模板:
template class Array<double>;
template class Array<int>;
进一步解释: 导出 dll 中未解析的外部模板类
我准备了一个VS 2017项目示例: http://www.mediafire.com/file/thxcz2dqplyqszb/ConsoleApplication5.zip/file
相关文章:
- g++用户定义的动态链接库上的全局new和delete运算符
- 如何使用C++导出制作动态链接库
- 动态链接库中C++回调函数
- 调用函数一次用于动态链接库,一次从可执行文件调用函数
- 将函数传递给动态链接库
- aarch64动态链接器rpath使用辅助依赖链接
- 如何将动态链接库与CMake一起使用
- 从另一个动态链接库项目调用静态库函数
- JNI 不满意链接错误: 动态链接库 (DLL) 初始化例程失败
- 如何将此动态链接库链接到程序
- Ordinal 3283不能位于动态链接库libmysql.dll中
- 检查动态链接库是否已过时
- Qt测试模拟动态链接库
- SDL_AudioStreamFlush无法在动态链接库SDL2_mixer.dll中找到
- 在 Win 7 SP 中创建 exe vcxproj:过程入口点<function>无法位于动态链接库中KERNAL32.dll
- 编译C++中动态链接库,存在运行路径问题
- 导入库<>动态链接库兼容性
- Java/Python在C/C++中访问的动态链接库
- 多个动态链接库(DLL)是否可以从静态库(LIB)共享线程本地存储
- 将静态库封装在动态链接库(DLL)中