0

I am creating a Python wrapper for an existing code base with a DLL and header. I am using SWIG.

The code base has multiple struct pointer defs like so:

typedef struct session* session_t;

In this example, session is not defined anywhere else. All other functions in the DLL take session_t as an input. If I try and reference session anywhere in SWIG generated code I get compile errors that session is not defined. I need a way to access the value of session_t in Python code.

I've tried using cpointer.i and pointer_functions macro, but this doesn't work since it assumes the input type is not a pointer.

I thought if I could redefine the struct:

typedef struct Session {} session, *session_t;

This could work, but I cant find a way to do this with SWIG.

Is there a way to access the value of a struct pointer with SWIG if it's only definition is a typdef struct pointer?

Edit: possible fix is the SWIG %ignore directive. Might be able to ignore the original struct def and replace it in the .i file.

Solved(ish): I marked Mark Tolonen's answer as correct since it has a lot of useful relevant information. The API I'm trying to wrap has a lot of deleted constructors and behaviors locking down how it's used. I ended up writing a C++ wrapper in it's own namespace then telling Swig to ignore everything except my namespace. I then only use standard or my own types to interface with Swig/Python.

3
  • A possible workaround is to complete the structure declaration, e.g. put struct session {}; somewhere in the header file. This way, you must also ensure that you never allocate a struct session by yourself. Commented Sep 15, 2018 at 1:35
  • You need a factory function like session_t session_open(void) which returns a new instance of session_t (like e.g. fopen). Commented Sep 15, 2018 at 6:42
  • I anticipate that you have some function, which creates a session* and perhaps other functions, which use session*. Take a lot at this answer, stackoverflow.com/questions/32478649/… The base class can be replaced with a simple typedef to make it more C like Commented Sep 16, 2018 at 17:29

1 Answer 1

2

SWIG works very well with opaque types. Here's a full example where I've provided the source for a test.dll that uses an opaque typedef. The structure is only defined within the .c file and SWIG has no knowledge of the definition. If you are still having a problem update your question with a reproducible example. I suspect you've used session instead of session_t in some typemap, but without a reproducible example I can only show that it works without a definition.

test.c

#define API_EXPORTS
#include <stdlib.h>
#include "test.h"

struct session {
    int a;
};

API session_t alloc(void) {
    session_t s = malloc(sizeof(session_t));
    if(s)
        s->a = 123;
    return s;
}

API int get_a(session_t s) {
    return s->a;
}

API void release(session_t s) {
    free(s);
}

test.h

#ifdef API_EXPORTS
#   define API __declspec(dllexport)
#else
#   define API __declspec(dllimport)
#endif

typedef struct session* session_t;

API session_t alloc(void);
API int get_a(session_t s);
API void release(session_t session);

test.i

%module test
%{
#include "test.h"
%}

%include <windows.i>
%include "test.h"

test session

Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:19:30) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> s = test.alloc()
>>> test.get_a(s)
123
>>> test.release(s)
>>>
Sign up to request clarification or add additional context in comments.

4 Comments

I had this in mind as well, but I think OP is asking how to get a session_t without an alloc function, i.e. something like for C++ classes where you can get an instance using test.Class().
@Henri A DLL that uses an opaque pointer without a way to obtain one? That makes no sense, but the OP is free to clarify.
Yeah this is a combination of less than idea DLL src and me not being a C expert. Since session_t is a pointer does sizeof(session_t) give the size of a pointer or the structure it's pointing to?
@Geordie sizeof(session_t) gives the size of the pointer. I would expect some API of the DLL to be something like OpenSession() and return a session_t somehow, similar to my demo with alloc().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.