Help us understand the problem. What is going on with this article?

ctypesで文字列を扱う

More than 1 year has passed since last update.

文字列のラップ

Pythonで文字列を引数にとる関数のラッピングをします.

c
#include <stdio.h>

void print_string(char* string)
{
  printf("%s\n", string);
}

int main(void)
{
  char string[] = "Hello World!";
  print_string(string);


  return 0;
}

以上のプログラムでprint_string関数は文字列を引数にとり,そのまま出力しています.

これをラップするPythonプログラムは以下のとおりです.

Python
import ctypes

libc = ctypes.cdll.LoadLibrary('./libstring.so')
str = 'Hello World!'
enc_str = str.encode('utf-8')
str = ctypes.create_string_buffer(enc_str)

libc.print_string(str)

他のラップツールはどうか知りませんが,ctypesで文字列を扱うときにはPython側で文字列の型付けをきちんとしなければなりません.

encode, create_string_bufferをしている2行を消すと,以下のように1文字しか出力されません.

H

文字列配列のラップ

c
#include <stdio.h>

void print_str_ary(int n, char** str_ary)
{
  int i;
  for(i = 0; i < n; i++){
    printf("%s\n", str_ary[i]);
  }
}

int main(void)
{
  int n = 3;
  char* str_ary[] = {"Hello", "World", "!"};
  print_str_ary(n, str_ary);

  return 0;
}

以上の文字列配列を受け取り出力する関数をラップします.

Python
import ctypes

libc = ctypes.cdll.LoadLibrary('./libstring_array.so')
hello = ['Hello', 'World', '!']
str_ary = (ctypes.POINTER(ctypes.c_char) * len(hello))()

for i, str in enumerate(hello):
    enc_str = str.encode('utf-8')
    str_ary[i] = ctypes.create_string_buffer(enc_str)

libc.print_str_ary(len(str_ary), str_ary)

char型のポインターが3つ有ることをあらかじめ示しています.この方法と別に,引数の方を予め宣言する方法があるみたいなのですが,調べきれていません.

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away