You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LibTorch C++封装库供C程序调用时链接失败求助

问题:LibTorch C++库导出C接口时链接失败

尝试制作一个LibTorch C++库,通过extern "C"导出函数供C程序调用。库的编译与链接看似正常,但主可执行文件无法完成链接。已将libtorch/lib下所有文件复制到/lib/目录,编译器报出大量LibTorch函数的未定义引用错误。

最小复现代码

Makefile

CFLAGS = -fPIC -Wall -Wshadow -O3 -pthread -I./
CFLAGS2 = -fPIC -Wall -O3 -pthread -I./
LDLIBS = -lm

all: libnet test

libnet: 
    g++ -shared -o ./libnet.so ./libnet.cpp $(CFLAGS2) \
      -I../../libtorch/include/ \
      -I../../libtorch/include/torch/csrc/api/include -L/lib \
      $(LDLIBS) -ltorch

test: 
    gcc -o ./test.exe ./test.c $(CFLAGS) $(LDLIBS) -ltorch ./libnet.so

C主程序 test.c

#include <libnet.h>

int main() {
  void* lstm = create_lstm(2, 64, 256, 1, 60);
}

C头文件 libnet.h

void* create_lstm(int layers, int hidden, int nbinputs, int outputs, int batchsize);

库文件 libnet.cpp

#include <torch/torch.h>

using namespace torch;

struct LSTM_Model : torch::nn::Module {
    torch::nn::LSTM lstm{ nullptr };
    torch::nn::Linear linear{ nullptr };
    torch::optim::Adam* opt{ nullptr };
    uint64_t _batchsize;
    uint64_t _hidden;

    LSTM_Model(uint64_t layers, uint64_t hidden, uint64_t inputs,
               uint64_t outputs, uint64_t batchsize) {
        lstm = register_module("lstm", torch::nn::LSTM(
                   torch::nn::LSTMOptions(inputs, hidden)
                   .num_layers(layers)));
        linear = register_module("linear", torch::nn::Linear(
                   hidden, outputs));
    _batchsize = batchsize;
    _hidden = hidden;
    }

    torch::Tensor forward(torch::Tensor x) {
        auto lstm1 = lstm->forward(x.view({ x.size(0), _batchsize, -1 })); 
        auto out = linear->forward(
                  std::get<0>(lstm1)
                  .view({ _batchsize, x.size(0), _hidden }));
        return out; 
    }
};

extern "C" void* create_lstm(int layers, int hidden, int nbinputs,
                             int outputs, int batchsize) {
  LSTM_Model* model = new LSTM_Model(layers, hidden, nbinputs, outputs, batchsize);
    model->opt = new torch::optim::Adam(model->parameters(),
                       torch::optim::AdamOptions(2e-4).
                         betas(std::make_tuple(0.5, 0.5)));
  return (void*)model;
}

链接错误信息(中文翻译)

/usr/bin/ld : ./libnet.so : 未定义的引用 « vtable for torch::optim::Optimizer »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::to(c10::Device, c10::ScalarType, bool) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::LSTMOptions::LSTMOptions(long, long) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « c10::detail::torchInternalAssertFail(char const*, char const*, unsigned int, char const*, char const*) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::LSTMImpl::LSTMImpl(torch::nn::LSTMOptions const&) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::train(bool) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::LinearOptions::LinearOptions(long, long) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « typeinfo for torch::nn::Module »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::is_serializable() const »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::pretty_print(std::ostream&) const »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::zero_grad(bool) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « vtable for torch::nn::Module »
/usr/bin/ld : ./libnet.so : 未定义的引用 « vtable for torch::optim::AdamOptions »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::optim::OptimizerParamGroup::options() const »
/usr/bin/ld : ./libnet.so : 未定义的引用 « typeinfo for torch::nn::LinearImpl »
/usr/bin/ld : ./libnet.so : 未定义的引用 « c10::detail::torchCheckFail(char const*, char const*, unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::optim::AdamOptions::AdamOptions(double) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « c10::UndefinedTensorImpl::_singleton »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::LinearImpl::LinearImpl(torch::nn::LinearOptions const&) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::clone(std::optional<c10::Device> const&) const »
/usr/bin/ld : ./libnet.so : 未定义的引用 « vtable for torch::optim::Adam »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::to(c10::ScalarType, bool) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::parameters(bool) const »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::optim::OptimizerParamGroup::has_options() const »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::is_training() const »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::to(c10::Device, bool) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::optim::OptimizerParamGroup::params() const »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::optim::Optimizer::add_param_group(torch::optim::OptimizerParamGroup const&) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « c10::detail::torchCheckFail(char const*, char const*, unsigned int, char const*) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::load(torch::serialize::InputArchive&) »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::save(torch::serialize::OutputArchive&) const »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::Module() »
/usr/bin/ld : ./libnet.so : 未定义的引用 « torch::nn::Module::clone_(torch::nn::Module&, std::optional<c10::Device> const&) »
collect2: error: ld returned 1 exit status
make: *** [Makefile:14 : test] 错误 1

解决方法

1. 链接完整的LibTorch依赖库

仅链接-ltorch不足以覆盖所有依赖,需要添加-ltorch_cpu、-lc10等核心库。推荐使用LibTorch自带的torch-config工具自动获取正确的编译和链接参数:

g++ -shared -o ./libnet.so ./libnet.cpp $(CFLAGS2) \
  -I../../libtorch/include/ \
  -I../../libtorch/include/torch/csrc/api/include \
  -L../../libtorch/lib \
  $(LDLIBS) `../../libtorch/bin/torch-config --cxxflags --libs`

2. 编译共享库时指定动态库路径

添加-Wl,-rpath,../../libtorch/lib参数,让链接器记录LibTorch库的路径,避免运行时和链接时找不到依赖:

g++ -shared -o ./libnet.so ./libnet.cpp $(CFLAGS2) \
  -I../../libtorch/include/ \
  -I../../libtorch/include/torch/csrc/api/include \
  -L../../libtorch/lib \
  -Wl,-rpath,../../libtorch/lib \
  $(LDLIBS) -ltorch -ltorch_cpu -lc10

3. 用g++编译C主程序

虽然主程序是C代码,但libnet.so是C编译的,链接时需要C标准库支持,因此用g++替代gcc编译test.exe:

g++ -o ./test.exe ./test.c $(CFLAGS) $(LDLIBS) -L../../libtorch/lib -Wl,-rpath,../../libtorch/lib -ltorch ./libnet.so

4. 避免手动复制LibTorch库到系统目录

直接使用LibTorch自带的lib路径更可靠,复制到/lib可能引发版本不匹配或权限问题。


内容的提问来源于stack exchange,提问作者Bertrand125

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 14:20:54