gpt4 book ai didi

python - 使用ctypes时如何替换libm?

转载 作者:太空狗 更新时间:2023-10-29 23:20:20 25 4
gpt4 key购买 nike

当一个函数(来自共享库)由一个独立的可执行文件执行时,以及当使用 Python 的 ctypes 调用完全相同的函数时,我得到了相同共享库的不同结果。
差异缩小为库使用的 libm 版本。
当从独立的可执行文件中使用库时,我们链接到 openlibm,但是当库通过 ctypes 链接时,它链接到 Ubuntu 的 libm。如何让 ctypes 将我的共享库链接到 openlibm

共享库头文件 (fft.h):

extern "C" {
void fft(const char* srcPath);
};

共享库实现(fft.cpp):

#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
#include <Eigen/Eigen>
#include <unsupported/Eigen/FFT>

void fft(const char* srcPath) {
std::cout.precision(17);

std::ifstream fs(srcPath, std::ofstream::in);

// Get length of file
fs.seekg(0, std::ifstream::end);
auto length = fs.tellg();
fs.seekg(0, std::ifstream::beg);

// Read the file
auto srcRaw = new char[length];
fs.read(srcRaw, length);

// Convert data to vector of doubles
nlohmann::json j = nlohmann::json::parse(srcRaw);
std::vector<double> srcDoubles = j;

int n = 65536;

Eigen::VectorXd srcEigen(n);
Eigen::VectorXcd dstEigen(n);
std::copy(srcDoubles.data(), srcDoubles.data() + srcDoubles.size(), srcEigen.data());

Eigen::FFT<double> fft;
fft.fwd(dstEigen, srcEigen);

std::vector<std::complex<double>> dstTmp(dstEigen.data(), dstEigen.data() + dstEigen.size());

for (size_t i = 0; i < dstTmp.size(); i++) {
std::cout << "Result[" << i << "] = " << dstTmp[i].real() << "+i*" << dstTmp[i].imag() << std::endl;
}

delete[] srcRaw;
}

从独立的可执行文件中使用库:

#include <fft.h>

int main(int argc, char** argv) {
fft("input_data");
}

使用 Python 的 ctypes:

from ctypes import c_char_p, CDLL


class LibCFft(CDLL):
def __init__(self):
super(LibCFft, self).__init__("libexample.so")
self._addfunc('fft', [c_char_p], None)

def _addfunc(self, name, argtypes, restype):
attr = getattr(self, name)
attr.argtypes = argtypes
attr.restype = restype

return lambda x: x


class CFft(object):
def fft(self):
LibCFft().fft("input_data")


if __name__ == '__main__':
CFft().fft()

库构建:

clang++ /opt/eigen-eigen-43d9075b23ef -isystem /opt/spdlog/include -isystem /opt/nlohmann/include -O3 -DNDEBUG -fPIC -std=gnu++14 -o CMakeFiles/example.dir/fft.cpp.o -c /home/user/fft.cpp

clang++ -fPIC -O3 -DNDEBUG -shared -Wl,-soname,libexample.so -o libbugatone.so CMakeFiles/example.dir/generated/fft.cpp.o -lopenlibm

可执行构建:

clang++ -O3 -DNDEBUG -latomic -nodefaultlibs -lopenlibm -lc -lc++ -lgcc -lgcc_s -lstdc++ -latomic -lm  CMakeFiles/eigen_tester.dir/eigen_tester.cpp.o  -o eigen_tester libexample.so -lopenlibm

在此先感谢您的帮助。

最佳答案

在可执行链接步骤中,您同时使用了 -lm 和 -lopenlibm,这可能不是您想要的。

-nodefaultlibs 禁用所有标准库的自动包含,所以如果你只是不包含 -lm 但保留 -lopenlibm,这应该可以做你想做的。

您可以在您的环境中更新 LD_LIBRARY_PATH,首先指向您的本地库文件夹,并将您的 libopenlibm.so 保留在那里并创建一个指向它的软链接(soft link):'ln -s libopenlibm.so libm.so'。在大多数情况下,这会导致任何共享对象使用它作为常规 libm.so 的替代

关于python - 使用ctypes时如何替换libm?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52139846/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com