ctypesでC言語側の配列データを取得する方法

// c_hoge.cpp
#include "c_hoge.h"
#include <stdlib.h>

static int numData = 0;
static float* arData = NULL;

void getArrayData(float** ppMem, int* pSize)
{
    if (!arData) {
        numData = 10000;
        arData = new float[numData];
        for (int i=0; i<numData; i++) {
            arData[i] = i;
        }
    }
    *pSize = numData;
    *ppMem = arData;
}
// c_hoge.h
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

__declspec(dllexport) void getArrayData(float** ppMem, int* pSize);

#ifdef __cplusplus
}
#endif

g++でDLLを作成。

> g++ -static -shared -o c_hoge.dll c_hoge.cpp
# test.py
from ctypes import *
import sys

cdll = cdll.LoadLibrary('c_hoge.dll')

getArrayData = cdll.getArrayData
getArrayData.argtypes = [POINTER(POINTER(c_float)), POINTER(c_int)]
getArrayData.restype = None

mem = POINTER(c_float)()
size = c_int(0)
getArrayData(byref(mem), byref(size))
print size.value, mem[0], mem[1], mem[2:4], mem[size.value-1]

実行結果。

>python test.py
10000 0.0 1.0 [2.0, 3.0] 9999.0

QStringとstd::wstringの変換

/*! Convert a QString to an std::wstring */
std::wstring qToStdWString(const QString &str)
{
#ifdef _MSC_VER
    return std::wstring((const wchar_t *)str.utf16());
#else
    return str.toStdWString();
#endif
}

/*! Convert an std::wstring to a QString */
QString stdWToQString(const std::wstring &str)
{
#ifdef _MSC_VER
    return QString::fromUtf16((const ushort *)str.c_str());
#else
    return QString::fromStdWString(str);
#endif
}

CAtlMapでユーザー定義型

以下、CAtlMapでキーにユーザ定義型を使用する方法。
Traitsの場合。
Traitsを使用しない場合は、DWORD()をオーバーロードしてハッシュ関数を定義する。

#include <atlcoll.h>

class Node
{
public:
    long nid;
    float xyz[3];
    Node() : nid(0) {}
    Node(long nid) : nid(nid) {}

    // compare operator
    BOOL operator==(const Node& in) const {
        if (nid == in.nid) return TRUE;
        return FALSE;
    }

    /*
    // operator to return random DWORD value for HashKey()
    operator DWORD() const throw(){
        return (DWORD)(this->nid);
    }

    // copy
    Node& operator=(const Node& in) {
        nid = in.nid;
        xyz[0]=in.xyz[0]; xyz[1]=in.xyz[1]; xyz[2]=in.xyz[2];
        return *this;
    }
    */
};

struct NodeTraits : public ATL::CElementTraits<Node>
{
    static ULONG Hash( const Node& t ) { return t.nid; }
    static bool CompareElements( const Node& e1, const Node& e2 )
        { return e1.nid==e2.nid; }
};

int main()
{
    CAtlMap<Node,float,NodeTraits> m;
    //m.InitHashTable(10);
    m[Node(1)] = 10.0;
    m[Node(2)] = 20.0;
    m[Node(3)] = 30.0;
    m[Node(4)] = 40.0;
    m[Node(3)] = 50.0;

    printf("v=%f\n", m[Node(2)]);
    printf("v=%f\n", m[Node(3)]);
}