- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我今天开始了一个小实验:我编写了一个依赖于其他一些库(ALGLIB、Eigen、内部工具)的 C++ 类,我想为该类创建一个 Ruby 包装器。我目前正在使用 Rice要做到这一点。首先,我为我的类编写了一个非常简单的 C++ 包装器:
// @file MLPWrapper.h
#pragma once
#include "mlp/MLP.h"
#include <ruby.h>
class MLPWrapper
{
MLP mlp; // <- my C++ class
public:
...
void fit()
{
...
mlp.fit(stop);
}
};
库的 cpp 文件是这样的:
// @file cmlp.cpp
#include "rice/Data_Type.hpp"
#include "rice/Constructor.hpp"
#include "MLPWrapper.h"
using namespace Rice;
extern "C"
void Init_cmlp()
{
Data_Type<MLPWrapper> rb_cMLPWrapper = define_class<MLPWrapper>("MLP")
.define_constructor(Constructor<MLPWrapper>())
...
.define_method("fit", &MLPWrapper::fit);
}
这是 extconf.rb:
require "mkmf-rice"
$CFLAGS << "-O3"
HEADER_DIRS = [
"..",
"../../external/libraries/eigen-eigen-3.0.1",
"../../external/libraries/alglib/cpp/src",
"../../external/libraries/CMA-ESpp"
]
LIB_DIRS = [
"../../build/external/libraries/alglib/cpp/src",
"../../build/external/libraries/CMA-ESpp/cma-es",
"../../build/src/tools"
]
dir_config("libs", HEADER_DIRS, LIB_DIRS)
have_library("libtools")
have_library("libalglib")
create_makefile("cmlp")
除链接外一切正常。显然库的头文件是包含的,否则编译不了。但是当我在 Ruby 中运行一个小测试程序(“require “cmlp”;mlp = MLP.new”)时,它没有找到符号 _ZN6LoggerC1ENS_6TargetESs,它是 libtools(枚举)的一部分。这是我构建 C++ 扩展并执行测试程序时发生的情况:
$ ruby extconf.rb
checking for main() in -lrice... yes
checking for main() in -llibtools... no
checking for main() in -llibalglib... no
checking for main() in -llibcmaes... no
creating Makefile
$ make
g++ -I. -I. -I/usr/lib/ruby/1.8/x86_64-linux -I. -I.. -I../../external/libraries/eigen-eigen-3.0.1 -I../../external/libraries/alglib/cpp/src -I../../external/libraries/CMA-ESpp -I/var/lib/gems/1.8/gems/rice-1.4.3/ruby/lib/include -fPIC -fno-strict-aliasing -g -g -O2 -fPIC -O3 -Wall -g -c cmlp.cpp
g++ -shared -o cmlp.so cmlp.o -L. -L/usr/lib -L../../build/external/libraries/alglib/cpp/src -L../../build/external/libraries/CMA-ESpp/cma-es -L../../build/src/tools -L. -Wl,-Bsymbolic-functions -rdynamic -Wl,-export-dynamic -L/var/lib/gems/1.8/gems/rice-1.4.3/ruby/lib/lib -lrice -lruby1.8 -lpthread -lrt -ldl -lcrypt -lm -lc
$ ruby test.rb
ruby: symbol lookup error: ./cmlp.so: undefined symbol: _ZN6LoggerC1ENS_6TargetESs
这些库都是用 CMake (add_library(...)) 编译的,位于
../../build/src/tools/libtools.so
../../build/external/libraries/alglib/cpp/src/libalglib.so
../../build/external/libraries/CMA-ESpp/cma-es/libcmaes.so
我不知道如何自己解决这个问题,也找不到任何对我的问题有帮助的文档。我该如何修复这个 extconf.rb?我感谢每一个提示。
编辑:好的,我更改了 extconf.rb:
require "rubygems"
require "mkmf-rice"
BASE_DIR = "/bla/"
$CFLAGS << " -O3"
dir_config("tools", [BASE_DIR + "src", BASE_DIR + "external/libraries/eigen-eigen-3.0.1"], BASE_DIR + "build/src/tools")
unless have_library("tools")
abort "tools are missing. please compile tools"
end
dir_config("alglib", BASE_DIR + "external/libraries/alglib/cpp/src", BASE_DIR + "build/external/libraries/alglib/cpp/src")
unless have_library("alglib")
abort "alglib is missing. please compile alglib"
end
dir_config("cmaes", BASE_DIR + "external/libraries/CMA-ESpp", BASE_DIR + "build/external/libraries/CMA-ESpp/cma-es")
unless have_library("cmaes")
abort "cmaes is missing. please compile cmaes"
end
create_makefile("cmlp")
生成的 Makefile 是:
SHELL = /bin/sh
#### Start of system configuration section. ####
srcdir = .
topdir = /usr/lib/ruby/1.8/x86_64-linux
hdrdir = $(topdir)
VPATH = $(srcdir):$(topdir):$(hdrdir)
exec_prefix = $(prefix)
prefix = $(DESTDIR)/usr
sharedstatedir = $(prefix)/com
mandir = $(prefix)/share/man
psdir = $(docdir)
oldincludedir = $(DESTDIR)/usr/include
localedir = $(datarootdir)/locale
bindir = $(exec_prefix)/bin
libexecdir = $(prefix)/lib/ruby1.8
sitedir = $(DESTDIR)/usr/local/lib/site_ruby
htmldir = $(docdir)
vendorarchdir = $(vendorlibdir)/$(sitearch)
includedir = $(prefix)/include
infodir = $(prefix)/share/info
vendorlibdir = $(vendordir)/$(ruby_version)
sysconfdir = $(DESTDIR)/etc
libdir = $(exec_prefix)/lib
sbindir = $(exec_prefix)/sbin
rubylibdir = $(libdir)/ruby/$(ruby_version)
docdir = $(datarootdir)/doc/$(PACKAGE)
dvidir = $(docdir)
vendordir = $(libdir)/ruby/vendor_ruby
datarootdir = $(prefix)/share
pdfdir = $(docdir)
archdir = $(rubylibdir)/$(arch)
sitearchdir = $(sitelibdir)/$(sitearch)
datadir = $(datarootdir)
localstatedir = $(DESTDIR)/var
sitelibdir = $(sitedir)/$(ruby_version)
CC = gcc
LIBRUBY = $(LIBRUBY_SO)
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
LIBRUBYARG_STATIC = -lruby1.8-static
RUBY_EXTCONF_H =
CFLAGS = -fPIC -fno-strict-aliasing -g -g -O2 -fPIC $(cflags) -O3
INCFLAGS = -I. -I. -I/usr/lib/ruby/1.8/x86_64-linux -I.
DEFS =
CPPFLAGS = -I/bla/external/libraries/CMA-ESpp -I/bla//external/libraries/alglib/cpp/src -I//bla/src -I/bla/external/libraries/eigen-eigen-3.0.1 -I/var/lib/gems/1.8/gems/rice-1.4.3/ruby/lib/include
CXXFLAGS = $(CFLAGS) -Wall -g
ldflags = -L. -Wl,-Bsymbolic-functions -rdynamic -Wl,-export-dynamic -L/var/lib/gems/1.8/gems/rice-1.4.3/ruby/lib/lib
dldflags =
archflag =
DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
LDSHARED = g++ -shared
AR = ar
EXEEXT =
RUBY_INSTALL_NAME = ruby1.8
RUBY_SO_NAME = ruby1.8
arch = x86_64-linux
sitearch = x86_64-linux
ruby_version = 1.8
ruby = /usr/bin/ruby1.8
RUBY = $(ruby)
RM = rm -f
MAKEDIRS = mkdir -p
INSTALL = /usr/bin/install -c
INSTALL_PROG = $(INSTALL) -m 0755
INSTALL_DATA = $(INSTALL) -m 644
COPY = cp
#### End of system configuration section. ####
preload =
CXX = g++
libpath = . $(libdir) /bla/external/libraries/CMA-ESpp/cma-es /bla/build/external/libraries/alglib/cpp/src /bla/build/src/tools
LIBPATH = -L. -L$(libdir) -L/bla/build/external/libraries/CMA-ESpp/cma-es -L/bla/build/external/libraries/alglib/cpp/src -L/bla/build/src/tools
DEFFILE =
CLEANFILES = mkmf.log
DISTCLEANFILES =
extout =
extout_prefix =
target_prefix =
LOCAL_LIBS =
LIBS = -lcmaes -lalglib -ltools -lrice -lruby1.8 -lpthread -lrt -ldl -lcrypt -lm -lc
SRCS = cmlp.cpp
OBJS = cmlp.o
TARGET = cmlp
DLLIB = $(TARGET).so
EXTSTATIC =
STATIC_LIB =
BINDIR = $(bindir)
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
TARGET_SO = $(DLLIB)
CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
all: $(DLLIB)
static: $(STATIC_LIB)
clean:
@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
distclean: clean
@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
realclean: distclean
install: install-so install-rb
install-so: $(RUBYARCHDIR)
install-so: $(RUBYARCHDIR)/$(DLLIB)
$(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
install-rb: pre-install-rb install-rb-default
install-rb-default: pre-install-rb-default
pre-install-rb: Makefile
pre-install-rb-default: Makefile
$(RUBYARCHDIR):
$(MAKEDIRS) $@
site-install: site-install-so site-install-rb
site-install-so: install-so
site-install-rb: install-rb
.SUFFIXES: .c .m .cc .cxx .cpp .C .o
.cc.o:
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
.cxx.o:
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
.cpp.o:
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
.C.o:
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
.c.o:
$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
$(DLLIB): $(OBJS) Makefile
@-$(RM) $@
$(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
$(OBJS): ruby.h defines.h
最佳答案
../../build/src/tools/libtools.so
../../build/external/libraries/alglib/cpp/src/libalglib.so
../../build/external/libraries/CMA-ESpp/cma-es/libcmaes.so
可能是问题所在。我会在这里尝试绝对路径,我可以想象 pwd 与您在运行 ruby extconf.rb
时预期的不同。此外,我假设您需要为每个要链接的库创建一个 dir_config
条目。所以
dir_config('libs', HEADER_DIRS, LIB_DIRS)
应该替换为
dir_config('tools', '<Path to include dir>', '<Path to lib dir>')
dir_config('alglib', '<Path to include dir>', '<Path to lib dir>')
请注意,前导的“lib”应该被省略,就像您在 -l 链接器选项中所做的那样。接下来,如果您想绝对确定找到了一个库,请替换
have_library('libtools')
通过
have_library('tools') or raise
同样,“lib”被省略了。
如果还是不能解决问题,请贴出`ruby extconf.rb'生成的Makefile。
关于带有外部库的 C++ Ruby 扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9251554/
如何指示 webpack 排除所有 d3 模块? // does not work externals: { "d3-*": "d3" } 所以如果应用导入了d3-submod
这个问题在这里已经有了答案: 9年前关闭。 Possible Duplicate: What does “outer =>” really mean? 我在哪里可以找到有关信息 trait After
这是一个简单的循环,我正在尝试对性能进行基准测试。 var extremeLoop=function(n){ var time=new Date() var t=0; for(
问题+概述 下面是两个片段,其中包含最初隐藏的 div,然后通过单击 button 和 jQuery 的 .show() 显示。两个 div 都具有由外部样式表应用的 display: grid; 样
我有一个 HTML 页面和一个单独的 .js 文件,该文件包含在带有 的页面中标签。 这是我的 .js 文件: element = document.getElementById("test");
我在 linux 静态库项目中有 3 个文件,我想在两个类方法实现文件中使用的静态字段存在链接问题。我有 class1.h、class1main.cpp 和 class1utils.cpp。 clas
我正在尝试将颜色背景更改为默认背景颜色,当我点击输入框外 我尝试使用“null”或“none”但没有用? window.addEventListener('click', outsideClick);
我正在编写一个应用程序,要求用户在手机上选择各种类型的文件。我使用此代码启动文件选择器 Intent : Intent intent = new Intent(Intent.ACTION_GET_C
在 android 中,不可移动(内部)的外部存储和内部存储有什么区别?我不确定在哪里保存我的数据。我只需要保存一个人可以随时提取的游戏统计数据 谢谢 最佳答案 在许多较新的设备中,将不再有物理区别,
在 C++ 中,假设我们有这个头文件: myglobals.h #ifndef my_globals_h #define my_globals_h int monthsInYear = 12; #en
我正在尝试使用 externs 在 C++ 中连接到 Ada。这两种实现有什么区别? 实现A namespace Ada { extern "C" { int getN
这个问题在这里已经有了答案: Get selected element's outer HTML (30 个答案) 关闭 2 年前。 想象一下我们有这样的东西: Hello World 如果我们这样
假设我在模块的顶部有这个: Public Declare Function getCustomerDetails Lib "CustomerFunctions" () As Long 如果我从 VB6
我目前正在使用这段代码: var wordRandomizer = { run: function (targetElem) { var markup = this.creat
我们正在使用 SVN 试水,并以 Beanstalk 作为主机。我们的设置如下所示: 存储库:模块 模块一 模块二 模块 3 存储库:网站1 自定义网站代码 svn:对模块 1 的外部引用 svn:对
有没有办法在负载均衡器中设置自动外部 IP 分配给像谷歌这样的服务? 我在裸机上运行 Kubernetes。 谢谢 最佳答案 使用 nodePort 类型的服务,它会将您的服务绑定(bind)到所有节
是否有可能在 Controller 之外使用 generateUrl() 方法? 我尝试在带有 $this->get('router') 的自定义存储库类中使用它,但它没有用。 更新 我在这里找到了一
我目前正在尝试通过 Webpack 外部对象外部化 Angular 依赖项来缩短构建时间。到目前为止,我已经为 React 和其他小库实现了这一目标。 如果我只是移动 '@angular/compil
我想创建一个自动应用其他插件的插件(外部插件)。这要求在我称为“应用插件”之前为插件设置构建脚本依赖项。但是似乎我无法在插件中添加buildscript依赖项,或者得到了: 您不能更改处于未解析状态的
我是R包的创建者EnvStats . 有一个我经常使用的函数,叫做 stripChart .我刚开始学习ggplot2 ,并在过去几天里仔细研究了 Hadley 的书、Winston 的书、Stack
我是一名优秀的程序员,十分优秀!