首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在使用ctype时替换libm?

如何在使用ctype时替换libm?
EN

Stack Overflow用户
提问于 2018-09-02 18:14:51
回答 1查看 370关注 0票数 4

当一个函数(来自共享库)由一个独立的可执行文件执行时,以及当使用Python的ctype调用完全相同的函数时,对于同一个共享库,我得到了不同的结果。

差别缩小到库使用的libm版本。

当使用独立可执行文件库时,我们将链接到openlibm,但是当库通过ctype链接时,它将链接到Ubuntu的libm。如何使ctype与openlibm链接我的共享库

共享库头(fft.h):

代码语言:javascript
复制
extern "C" {
void fft(const char* srcPath);
};

共享库实现(fft.cpp):

代码语言:javascript
复制
#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;
}

使用独立可执行文件库的

代码语言:javascript
复制
#include <fft.h>

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

使用Python的ctype的

代码语言:javascript
复制
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()

Lib构建:

代码语言:javascript
复制
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

可执行构建:

代码语言:javascript
复制
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

提前谢谢你的帮助。

EN

回答 1

Stack Overflow用户

发布于 2018-09-02 20:04:00

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

-nodefaultlibs禁用了所有标准库的自动包含,因此,如果您只是简单地不包括-lm,而是保留-lopenlibm,这可能会做您想做的事情。

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

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52139846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档