how to access character pointer value using ctypes?
<p>I have a written a DLL in which I'm getting one of the paths:</p>

<pre><code>//demo.h
__declspec(dllexport) void pathinfo(char * path);
</code></pre>

<p>Something is being done in the code to get this path.
And now, the python script that I have written to retrieve this path from the DLL is as shown:</p>

<pre><code>//demo.py
import sys 
import ctypes
from ctypes import *
class demo(object):
  def __init__(self):
     self.demoDLL=CDLL("demo.dll")

  def pathinfo(self):
     path=c_char()
     self.demoDLL.pathinfo.argtypes(POINTER(c_char))
     self.demoDLL.pathinfo.result=None
     self.demoDLL.pathinfo(byref(path))
     return path.value

if __name__=='__main__':
    abc=demo()
    path_info=abc.pathinfo()
    print "information of the path:",path_info
</code></pre>

<p>But the value that I'm able to see is just the first character of the path instead of the whole string.</p>

<p>Can anybody help me with this problem?</p>

<p>The reason you see only the first character is that by calling <code>c_char()</code> you create a single <code>char</code> value that Python treats like a <code>str</code> (Python 2) object or <code>bytes</code> (Python 3) object of length 1. You are probably lucky that you do not get a segmentation fault. By writing more than 1 byte or a NULL-terminated string of length > 0 (e.g. with <code>strcpy</code>) in the C code, you actually produce an undetected buffer overflow. <code>ctypes</code> does not know how many bytes you have written at the pointer's memory location. <code>path.value</code> is still a <code>str</code> / <code>bytes</code> of length 1.</p>

<p>It would be better to change the C <code>pathinfo</code> function into someting like</p>

<pre><code>size_t pathinfo(char* path, size_t bsize);
</code></pre>

<p>Use <code>ctypes.create_string_buffer()</code> to allocate memory in your Python code and let <code>pathinfo</code> return the length of the result. Of course you have to check, whether <code>char* path</code> is large enough using <code>bsize</code> in your C-Code.</p>

<p>The Python-code would look like this:</p>

<pre><code>buf = ctypes.create_string_buffer(256)
result_len = pathinfo(buf, len(buf))
if result_len == len(buf):
    # buffer may have been too short,
    # try again with larger buffer
    ...
restlt_str = buf[0:result_len].decode('utf-8') # or another encoding
</code></pre>

<p>Also be aware of NULL-termination in the C domain, character encodings when converting python strings to <code>char*</code> and back, the changes regarding <code>str</code> / <code>bytes</code> in <code>ctypes</code> regarding Python 2 and Python 3.</p>

python dll ctypes