ctypes segfault仅在OSX上 [英] ctypes segfault on OSX only

查看:94
本文介绍了ctypes segfault仅在OSX上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用ctypes在Python中创建了一个非常简单的C库绑定.它所做的就是接受一个字符串并返回一个字符串.

I created a very simple C library binding in Python using ctypes. All it does is accept a string and return a string.

我在Ubuntu上进行了开发,一切看起来都很好.不幸的是,在OSX上,完全相同的代码失败.我完全迷住了.

I did the development on Ubuntu, and everything looked fine. Unfortunately, on OSX the exact same code fails. I'm completely stumped.

我整理了一个最小的案例来说明我遇到的问题.

I've put together a minimal case showing the issue I'm having.

import ctypes

# Compile for:
#   Linux: `gcc -fPIC -shared hello.c -o hello.so`
#   OSX:   `gcc -shared hello.c -o hello.so`
lib = ctypes.cdll.LoadLibrary('./hello.so')

# Call the library
ptr = lib.hello("Frank")
data = ctypes.c_char_p(ptr).value # segfault here on OSX only
lib.free_response(ptr)

# Prove it worked
print data

hello.c

#include <stdlib.h>
#include <string.h>

// This is the actual binding call.
char* hello(char* name) {
    char* response = malloc(sizeof(char) * 100);
    strcpy(response, "Hello, ");
    strcat(response, name);
    strcat(response, "!\n");
    return response;
}

// This frees the response memory and must be called by the binding.
void free_response(char *ptr) { free(ptr); }

推荐答案

您应指定函数的返回类型.具体来说,将其声明为 ctypes.POINTER(ctypes.c_char).

You should specify the return type of your function. Specifically, declare it to be ctypes.POINTER(ctypes.c_char).

import ctypes

lib = ctypes.CDLL('./hello.so')    
lib.hello.restype = ctypes.POINTER(ctypes.c_char)

ptr = lib.hello("Frank")
print repr(ctypes.cast(ptr, ctypes.c_char_p).value)
lib.free_response(ptr)

这篇关于ctypes segfault仅在OSX上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆