【发布时间】:2020-10-05 11:39:06
【问题描述】:
我最近发布了关于使用 DLL 函数的问题,自从我一直试图缩小问题范围以来。我重新创建了我的代码部分以仅包含 DLL 部分,这似乎是问题出现的地方。该库是一个 64 位库,我使用 Mingw64-g++ 进行编译。 下面的代码是加载dll,加载库函数,然后使用。使用库函数运行良好,但是在我有机会做任何事情之前,为以下调用分配内存失败(崩溃)。这是我目前拥有的代码。
#include <iostream>
#include <fstream>
#include <windows.h>
using namespace std;
typedef int WINAPI CompressFunc(uint32_t codec, char *src_buf, int64_t src_len, char *dst_buf, int64_t level,
void *opts, int64_t offs);
typedef int64_t WINAPI DecompressFunc(
char *src_buf, int64_t src_len, char *dst_buf, int64_t dst_size, int fuzz, int crc, int verbose,
uint8_t *dst_base, size_t e, void *cb, void *cb_ctx, void *scratch, size_t scratch_size, int threadPhase
);
int main()
{
string dll_path = "oo2core_5_win64.dll";
HINSTANCE dll_object = LoadLibraryA(dll_path.c_str());
cout<<GetLastError()<<endl;
string compress_function_name = "OodleLZ_Compress";
string decompress_function_name = "OodleLZ_Decompress";
CompressFunc* CompressFunc_Func;
DecompressFunc* DecompressFunc_Func;
CompressFunc_Func = (CompressFunc*)GetProcAddress(dll_object, compress_function_name.c_str());
DecompressFunc_Func = (DecompressFunc*)GetProcAddress(dll_object, decompress_function_name.c_str());
cout<<bool(CompressFunc_Func)<<" "<<bool(DecompressFunc_Func)<<endl;
ifstream fin("0.decompressed", ios::binary);
cout<<fin.good()<<endl; // Prints 1
fin.seekg(0, ios::end);
uint64_t decompressed_size = fin.tellg();
cout<<decompressed_size<<endl; //Prints 558, correct
fin.seekg(0);
cout<<fin.tellg()<<endl; // Prints 0
cout.flush();
char* decompressed_data = new char [decompressed_size];
fin.read(decompressed_data, decompressed_size);
cout<<"Read Data"<<endl;
cout.flush();
char* compressed_data;
compressed_data = new char [decompressed_size + 0x10000]; //Upper Bound
int64_t compressed_size = CompressFunc_Func(7, decompressed_data, decompressed_size, compressed_data, 7, 0, 0);
cout<<"Compressed Successfully"<<endl;
cout<<"Compressed Size: "<<compressed_size<<endl; // Prints 225
cout.flush();
for (int i = 0; i < 4; i++)
{
cout<<hex<<(uint16_t)compressed_data[i]<<" ";
}
cout<<dec<<endl;
delete [] decompressed_data;
cout<<"Still Deco Size: "<<decompressed_size<<endl; //Prints 558, correct
char* x = new char [decompressed_size]; // Freezes here then stops
//DecompressFunc_Func(compressed_data, compressed_size, decompressed_data, decompressed_size, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
输出:
0
1 1
1
558
0
Read Data
当我在底部评论内存分配时,输出:
0
1 1
1
558
0
Read Data
Compressed Successfully
Compressed Size: 225
ff8c 5 40 ffdc
Still Deco Size: 558
仅当内存分配在之后存在时,运行 GDB 调试器才会在 Compress 函数处产生分段错误。
【问题讨论】:
-
??????小心前行,看看会发生什么?
-
new调用似乎没有任何进展。您确定这是发生故障的地方吗? -
selbie 程序挂起然后就存在了。 @tadman 是的,我确实在 gdb 中运行过它,一旦在底部添加分配,它就会在我之前调用的 Compress 函数中产生分段错误,这让我感到困惑。当之后有分配时,压缩失败。
-
您的 dll 和主应用程序是否使用相同版本的 mingw 编译,因此您没有多个堆?我问是因为这些是我在混合 Visual Studio 版本时经常遇到的问题。