LoginSignup
7
10

More than 5 years have passed since last update.

ctypesで文字列を扱う

Posted at

文字列のラップ

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つ有ることをあらかじめ示しています.この方法と別に,引数の方を予め宣言する方法があるみたいなのですが,調べきれていません.

7
10
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10