我正在为 Linux 开发一个静态独立的 nolibc/nostdlib 程序,并希望使用 C 编译器的内存、地址和未定义行为清理程序来改进我的代码。
当我尝试时,我无法让它工作:
clang -static -ffreestanding -nostdlib -fno-omit-frame-pointer -fsanitize=undefined -g -o program program.c
Run Code Online (Sandbox Code Playgroud)
这会导致编译器发出调用诸如__ubsan_handle_type_mismatch_v1@plt. 它编译和链接成功,但程序在运行时在这些引用附近出现段错误。更具体地说,在我的内存分配器中:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) up
(gdb) disas
Dump of assembler code for function lone_reallocate:
...
0x00000000002116d0 <+160>: bl 0x206470 <__ubsan_handle_pointer_overflow@plt>
=> 0x00000000002116d4 <+164>: b 0x2116d8 <lone_reallocate+168>
0x00000000002116d8 <+168>: ldur x8, [x29, #-72]
...
Run Code Online (Sandbox Code Playgroud)
我认为这些函数由于缺乏 libc 支持而丢失。当我尝试使用该-static-libsan选项时,出现许多未定义的符号错误:
error: undefined symbol: __aarch64_cas8_acq_rel
error: undefined symbol: pthread_self
error: undefined symbol: dl_iterate_phdr
error: …Run Code Online (Sandbox Code Playgroud) 我正在编写一个定义类的ruby扩展.如果我Data_Wrap_Struct()用来实现我的回调rb_define_alloc_func(),我是否需要手动标记并释放实例变量?或者这仍然是为我处理的?
在红宝石中,
begin
# ...
rescue
# ...
end
Run Code Online (Sandbox Code Playgroud)
不会捕获不是子类的异常StandardError.在C中,
rb_rescue(x, Qnil, y, Qnil);
VALUE x(void) { /* ... */ return Qnil; }
VALUE y(void) { /* ... */ return Qnil; }
Run Code Online (Sandbox Code Playgroud)
会做同样的事情.我如何rescue Exception => e从ruby C扩展(而不仅仅是rescue => e)?
我想制作一个使用相机的Android应用程序,并在预览帧上应用图像处理过滤器.
package alex.filter;
import java.io.IOException;
import android.content.Context;
import android.graphics.Canvas;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
class Preview extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
public Camera camera;
Preview(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
for( int i = 0 ; i < data.length ; i ++ ){
data[ i] = 0; // or some …Run Code Online (Sandbox Code Playgroud) 在我的代码中,我需要使用各种算法来散列文件,包括CRC32.由于我还在家庭中使用其他加密哈希函数Digest,我认为为它们维护一致的接口会很好.
为了记录,我确实找到digest-crc了一个完全符合我想要的宝石.问题是,它Zlib是标准库的一部分,并且具有CRC32的工作实现,我想重用它.此外,它是用C语言编写的,因此它应该提供相对于digest-crc纯ruby实现的卓越性能.
实施Digest::CRC32实际上是在第一次看很简单:
%w(digest zlib).each { |f| require f }
class Digest::CRC32 < Digest::Class
include Digest::Instance
def update(str)
@crc32 = Zlib.crc32(str, @crc32)
end
def initialize; reset; end
def reset; @crc32 = 0; end
def finish; @crc32.to_s; end
end
Run Code Online (Sandbox Code Playgroud)
一切看起来都正确:
crc32 = File.open('Rakefile') { |f| Zlib.crc32 f.read }
digest = Digest::CRC32.file('Rakefile').digest!.to_i
crc32 == digest
=> true
Run Code Online (Sandbox Code Playgroud)
不幸的是,并非一切正常:
Digest::CRC32.file('Rakefile').hexdigest!
=> "313635393830353832"
# What I actually expected was:
Digest::CRC32.file('Rakefile').digest!.to_i.to_s(16)
=> "9e4a9a6"
Run Code Online (Sandbox Code Playgroud)
hexdigest基本上返回 …
我正在编写Ruby 1.9 C扩展,我想在ruby中执行以下操作:
notifier = Notifier.new
notifier.on 'click' do
puts "clicked!"
end
Run Code Online (Sandbox Code Playgroud)
现在问题是在C方法上,我只"接收"一个块,据我所知,它甚至不是一个参数:我只能用来调用rb_yield.
所以我的问题是:在Ruby 1.9 C扩展上是否有办法将块转换为proc或者其他东西,所以我可以将它存储在我的模块中,并在我想要/需要它时稍后调用它?就像一个异步回调!
我已经使用Procs/lambdas实现了这个,但是直接使用块语法真是太丑了.
我正在编写一个C扩展,提供Ruby和异步I/O库之间的接口.在我的代码上运行测试时,我经常会遇到错误,包括(但不限于):
[BUG] cross-thread violation in rb_thread_schedule()
Run Code Online (Sandbox Code Playgroud)
异步IO意味着我的C扩展需要从多个线程(而不是主解释器线程)向ruby传递消息.在此过程中如何避免这些线程安全违规?
我有以下路线:
resources :users do
# List reviews made by user
resources :reviews, :only => [ :index ]
end
resources :products do
# List reviews by product, and provide :product_id for creation
resources :reviews, :only => [ :index, :new, :create ]
end
# Other actions don't depend on other resources
resources :reviews, :except => [ :index, :new, :create ]
Run Code Online (Sandbox Code Playgroud)
一切看起来都是正确的,除了ReviewsController#index:
def index
if params[:user_id]
@reviews = Review.find_all_by_user_id params[:user_id]
else
@reviews = Review.find_all_by_product_id params[:product_id]
end
respond_with @reviews
end
Run Code Online (Sandbox Code Playgroud)
我想知道是否有上述问题的标准解决方案,或者是否有更好的方法来做到这一点.
我想这样组织C源代码:
+ /
|
|___ + ext
| |
| |___ + native_extension
| |
| |___ + lib
| | |
| | |___ (Source files are kept in here - may contain sub-folders)
| |
| |___ native_extension.c
| |___ native_extension.h
| |___ extconf.rb
|
|___ + lib
| |
| |___ (Ruby source code)
|
|___ Rakefile
Run Code Online (Sandbox Code Playgroud)
我无法让此设置正确使用mkmf。native_extension/lib中包含的中的文件native_extension.c,将被完全忽略。
构建扩展时,仅native_extension.{h,c}会进行编译,并且native_extension.{so,dll}在尝试运行扩展程序时出现不完整的符号查找错误。
有什么办法可以使这项工作吗?
我正在写一个包含C扩展的gem.通常当我写一个gem时,我会遵循TDD的过程,在那里我将编写一个失败的规范,然后处理代码直到它通过等等......
使用我在"ext/mygem/mygem.c"中的C扩展和在gemspec的"扩展"中配置的有效extconf.rb,如何运行我的规范并仍然加载了我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?
这可能是一个愚蠢的问题,但是从我的gem的开发源代码树里面输入'bundle install'并没有构建任何原生扩展.当我手动运行时,ruby ext/mygem/extconf.rb我得到一个Makefile(在整个项目的根目录中),当我运行时make,我确实得到了一个共享对象(同样,在整个项目的根目录中).我必须遵循错误的工作流程,因为我知道.so应该放在lib /下.除非我只是想在开发过程中手工做到这一点?