c_char_p HELP.....please

A forum for general discussion of the Python programming language.

c_char_p HELP.....please

Postby alabview » Wed Oct 09, 2013 4:04 pm

Code as below
Code: Select all
from ctypes import *
s = "INIT"
c_s=c_char_p(s)



The error after c_s=char_p(s)
Code: Select all
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    c_s = c_char_p(s)
TypeError: bytes or integer address expected instead of str instance


Please help....
alabview
 
Posts: 22
Joined: Mon Sep 16, 2013 1:48 pm

Re: c_char_p HELP.....please

Postby Yoriz » Wed Oct 09, 2013 4:54 pm

I tried your code, i got no error.
Code: Select all
Python 2.7.4 (default, Apr  6 2013, 19:54:46) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> from ctypes import *
>>> s = "INIT"
>>> c_s=c_char_p(s)
>>> c_s
c_char_p('INIT')
>>>
New Users, Read This
Join the #python-forum IRC channel on irc.freenode.net!
Image
User avatar
Yoriz
 
Posts: 1026
Joined: Fri Feb 08, 2013 1:35 am
Location: UK

Re: c_char_p HELP.....please

Postby micseydel » Wed Oct 09, 2013 5:52 pm

Your code is for Python 2, but you're using Python 3. Change the last line to
Code: Select all
c_s=c_char_p(s.encode())

(I have no idea why you need to do that, needing to randomly put .encode() in my code has been my biggest blocker to casually using Python 3.)
Join the #python-forum IRC channel on irc.freenode.net!

Please do not PM members regarding questions which are meant to be discussed publicly. The point of the forum is so that others can benefit from it. We don't want to help you over PMs or emails.
User avatar
micseydel
 
Posts: 1436
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

Re: c_char_p HELP.....please

Postby casevh » Wed Oct 09, 2013 9:07 pm

micseydel wrote:Your code is for Python 2, but you're using Python 3. Change the last line to
Code: Select all
c_s=c_char_p(s.encode())

(I have no idea why you need to do that, needing to randomly put .encode() in my code has been my biggest blocker to casually using Python 3.)


Very simplified discussion ahead...

In Python 2.x, the type of "ab" is "str". The letters "a" and "b" are stored as two C characters. Each "character" occupies precisely 8 bits. c_char_s() gets a pointer to the two C characters and everything works as expected.

In Python 3.x, the type of "ab" is "unicode". A Unicode string can support many different characters (i.e. other languages). Each "character" in a Unicode string may require 8, 16, or 32 bits. There are multiple ways to store Unicode character sets so the internal representation can vary. c_char_s() fails since a Unicode string can't be reliably interpreted as an array of 8 bit characters. encode() converts a Unicode string into a sequence of bytes. encode() assumes UTF-8 format for Unicode and, by default, raises an exception if an invalid character is found. The result of "ab".encode() is a "bytestring". Internally, a bytestring is an array of characters (bytes) so c_char_s("ab".encode()) succeeds.

Python 2.x supported a distinct "unicode" type but most programmers ignored Unicode and just worked with the generic (sequence of bytes) string type. This was a source of subtle bugs when Unicode strings and byte string intermixed. Python 3.x uses Unicode as the default type for "..." and uses bytestring as a sequence of bytes. Python 3 forces the programmer to care about the difference between stings (Unicode) and bytes. If you are interfacing with an external library via ctypes, you most likely want to use a sequence of bytes and you should use b"...".

I glossed over many of the details since I don't understand them...

casevh
casevh
 
Posts: 70
Joined: Sat Feb 09, 2013 7:35 am

Re: c_char_p HELP.....please

Postby micseydel » Wed Oct 09, 2013 9:22 pm

Thanks as always casevh for bringing to the table such information!
Join the #python-forum IRC channel on irc.freenode.net!

Please do not PM members regarding questions which are meant to be discussed publicly. The point of the forum is so that others can benefit from it. We don't want to help you over PMs or emails.
User avatar
micseydel
 
Posts: 1436
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

Re: c_char_p HELP.....please

Postby Marbelous » Wed Oct 09, 2013 10:17 pm

casevh wrote:
I glossed over many of the details since I don't understand them...

casevh

Still a very useful and informative post. :geek: Thanks for sharing!
Marbelous
 
Posts: 153
Joined: Fri May 31, 2013 8:12 pm

Re: c_char_p HELP.....please

Postby alabview » Thu Oct 10, 2013 12:15 pm

Hi micseydel,

Thanks for your information,

But,

I have a problem

Code: Select all
>>> from ctypes import *
>>> from sys import exit
>>> X = ("INIT")
>>> STATE=c_char_p(X.encode())


And

The return string is
Code: Select all
>>> STATE
c_char_p(b'INIT')


So, my question is

c_char_p(b'INIT') is a return string? If yes, how I am going to display/show the string i.e INIT ?
alabview
 
Posts: 22
Joined: Mon Sep 16, 2013 1:48 pm

Re: c_char_p HELP.....please

Postby casevh » Thu Oct 10, 2013 3:32 pm

Code: Select all
>>> from ctypes import *
>>> X="INIT".encode()
>>> X
b'INIT'
>>> STATE=c_char_p(X)
>>> STATE
c_char_p(b'INIT')
>>> STATE.value
b'INIT'
>>> STATE.value.decode()
'INIT'
>>>
casevh
 
Posts: 70
Joined: Sat Feb 09, 2013 7:35 am

Re: c_char_p HELP.....please

Postby alabview » Fri Oct 11, 2013 9:11 am

Hi caseh,

Thanks for your help, it help me alot...again TQ.

Meantime, as below code Pyhton 3.3 if I would like to use it in Pyhton 2.7, how it should be?

Code as below,

Code: Select all
>>> from ctypes import *
>>> STATE = "INIT"
>>> X = STATE.encode()
>>> STATETEMP=c_char_p(X)
>>> STATEREAL=STATETEMP.value.decode()
>>> STATEREAL
'INIT'
>>> CallDLL = cdll.LoadLibrary("C:\Python33\DLLs\\String.dll")
>>> Output=CallDLL.String
>>> OutputVariableStr=Output(STATEREAL)


Code: Select all
>>> print(STATEREAL)
INIT

Please advice.

Many Thanks.
Walter.
alabview
 
Posts: 22
Joined: Mon Sep 16, 2013 1:48 pm

Re: c_char_p HELP.....please

Postby casevh » Sat Oct 12, 2013 3:09 am

alabview wrote:Hi caseh,

Thanks for your help, it help me alot...again TQ.

Meantime, as below code Pyhton 3.3 if I would like to use it in Pyhton 2.7, how it should be?

Code as below,

Code: Select all
>>> from ctypes import *
>>> STATE = "INIT"
>>> X = STATE.encode()
>>> STATETEMP=c_char_p(X)
>>> STATEREAL=STATETEMP.value.decode()
>>> STATEREAL
'INIT'
>>> CallDLL = cdll.LoadLibrary("C:\Python33\DLLs\\String.dll")
>>> Output=CallDLL.String
>>> OutputVariableStr=Output(STATEREAL)


Code: Select all
>>> print(STATEREAL)
INIT

Please advice.

Many Thanks.
Walter.


I don't follow what your code is trying to do. STATE is a Unicode string containing "INIT". X is a byte-string that also contains "INIT". (They happen to be the roughly be the same since STATE doesn't contain any characters besides the standard ASCII characters, but that is coincidence.) STATETEMP points to the sequence of bytes in the byte-string that represents the letters I, N, I, T, and then followed by a 0x00 byte. STATEREAL is a Unicode string containing "INIT". So far, all you've done is convert "INIT" from Unicode to bytes and then from bytes to Unicode. STATETEMP still refers to the internal data of X (the byte string,)

You then call String.dll with the Unicode object STATEREAL. Did you intend to call it with STATETEMP?

The difference with Python 2.x is that objects created with quotes are already (more or less) byte-strings. So you can just skip the encode()/decode() steps. In Python 2.x, Unicode objects are created using u"...".

Code: Select all
$ py27
Python 2.7.5 (default, Aug  4 2013, 15:20:26)
[GCC 4.8.1 20130603 (Red Hat 4.8.1-1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> u"789"
u'789'
>>> b"789"
'789'
>>> exit()
$ py33
Python 3.3.2 (default, Aug  4 2013, 14:55:21)
[GCC 4.8.1 20130603 (Red Hat 4.8.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> u"789"
'789'
>>> b"789"
b'789'
>>>


casevh
casevh
 
Posts: 70
Joined: Sat Feb 09, 2013 7:35 am

Re: c_char_p HELP.....please

Postby alabview » Sun Oct 13, 2013 9:48 am

Hi Caseh,

I would like to pass a string INIT into String.dll and print/display INIT string from String.dll via Python.

Yes, I would like to call it from STATETEMP.

BTW, I skipped the encode()/decode() steps and the result what I have is 0 and no idea why.

Code: Select all
>>> from ctypes import *
>>> STATE = "INIT"
>>> CallDLL = cdll.LoadLibrary("C:\\Python27\\DLLs\\String.dll")
>>> Output=CallDLL.String
>>> OutputVariableStr=Output(STATE)
>>> print(OutputVariableStr)
0


Please advice and help. Sorry, Caseh I am new to python hopefully I am not giving you so much problem
alabview
 
Posts: 22
Joined: Mon Sep 16, 2013 1:48 pm

Re: c_char_p HELP.....please

Postby casevh » Sun Oct 13, 2013 6:45 pm

alabview wrote:Hi Caseh,

I would like to pass a string INIT into String.dll and print/display INIT string from String.dll via Python.

Yes, I would like to call it from STATETEMP.

BTW, I skipped the encode()/decode() steps and the result what I have is 0 and no idea why.

Code: Select all
>>> from ctypes import *
>>> STATE = "INIT"
>>> CallDLL = cdll.LoadLibrary("C:\\Python27\\DLLs\\String.dll")
>>> Output=CallDLL.String
>>> OutputVariableStr=Output(STATE)
>>> print(OutputVariableStr)
0


Please advice and help. Sorry, Caseh I am new to python hopefully I am not giving you so much problem


You are not using STATETEMP in the example you provided.

I have no idea what String.dll is supposed to do or how you should be calling it.

casevh
casevh
 
Posts: 70
Joined: Sat Feb 09, 2013 7:35 am

Re: c_char_p HELP.....please

Postby alabview » Mon Oct 14, 2013 9:54 am

Hi Caseh,

Sorry for not explain clearly,

If I skipped the encode()/decode() steps or vice versa and the result what I have is 0 and no idea why.

Code: Select all
>>> from ctypes import *
>>> STATE = "INIT"
>>> STATETEMP=c_char_p(STATE)
>>> CallDLL = cdll.LoadLibrary("C:\Python27\DLLs\\String.dll")
>>> Output=CallDLL.String
>>> OutputVariableStr=Output(STATETEMP)
>>> print(OutputVariableStr)
0
>>>


Basically, String.dll is a very simple Input and Output function.

For example,

Input as a String, Output as a String. For example

Input = "INIT"
Output also = "INIT"

Many Thanks.
Walter.
alabview
 
Posts: 22
Joined: Mon Sep 16, 2013 1:48 pm


Return to General Discussions

Who is online

Users browsing this forum: No registered users and 2 guests