Python Ctypes passing pointer for data Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!ctypes: decomposing/casting pointer to char into array of pointer to charPython ctypes : create user defined types and exchange with function in dllUpdating an LP_c_ubyte buffer created in a C DLLWhat are the differences between a pointer variable and a reference variable in C++?Calling an external command in PythonWhat are metaclasses in Python?What is a smart pointer and when should I use one?Finding the index of an item given a list containing it in PythonWhat is the difference between Python's list methods append and extend?How can I safely create a nested directory in Python?Does Python have a ternary conditional operator?How do I pass a variable by reference?Does Python have a string 'contains' substring method?
"Destructive force" carried by a B-52?
Coin Game with infinite paradox
What documents does someone with a long-term visa need to travel to another Schengen country?
Can gravitational waves pass through a black hole?
How to mute a string and play another at the same time
A German immigrant ancestor has a "Registration Affidavit of Alien Enemy" on file. What does that mean exactly?
What came first? Venom as the movie or as the song?
If gravity precedes the formation of a solar system, where did the mass come from that caused the gravity?
Proving inequality for positive definite matrix
Suing a Police Officer Instead of the Police Department
How to create a command for the "strange m" symbol in latex?
How can I introduce the names of fantasy creatures to the reader?
Protagonist's race is hidden - should I reveal it?
Why these surprising proportionalities of integrals involving odd zeta values?
Does traveling In The United States require a passport or can I use my green card if not a US citizen?
Putting Ant-Man on house arrest
Recursive calls to a function - why is the address of the parameter passed to it lowering with each call?
Is Bran literally the world's memory?
Why not use the yoke to control yaw, as well as pitch and roll?
What's the connection between Mr. Nancy and fried chicken?
What is the difference between 准时 and 按时?
Who can become a wight?
Pointing to problems without suggesting solutions
Has a Nobel Peace laureate ever been accused of war crimes?
Python Ctypes passing pointer for data
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!ctypes: decomposing/casting pointer to char into array of pointer to charPython ctypes : create user defined types and exchange with function in dllUpdating an LP_c_ubyte buffer created in a C DLLWhat are the differences between a pointer variable and a reference variable in C++?Calling an external command in PythonWhat are metaclasses in Python?What is a smart pointer and when should I use one?Finding the index of an item given a list containing it in PythonWhat is the difference between Python's list methods append and extend?How can I safely create a nested directory in Python?Does Python have a ternary conditional operator?How do I pass a variable by reference?Does Python have a string 'contains' substring method?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I am accessing an API and can't get the data returned. The two float pointers will point to an array of data. I must assume the API is working properly. A different function call provides a the length of the data I am retrieving. This values is length
down below when attempted.
C Header for Function
int function(int, float * data1, float * data2)
ctypes setup
dll.function.argtypes = (c_int, POINTER(c_float), POINTER(c_float))
dll.function.restypes = c_int
Failed Attempt 1:
x = c_float()
y = c_float()
status = dll.function(1, byref(x), byref(y))
Program crashes OR Access violation writing.
Failed Attempt 2:
x = POINTER(c_float)()
y = POINTER(c_float)()
status = dll.function(1, x, y)
Null Pointer Error
Failed Attempt 3:
dll.function.argtypes = (c_int, c_void_p, c_void_p)
x = c_void_p()
y = c_void_p()
status = dll.function(1, x, y)
Null Pointer Error
Failed Attempt 4:
array = c_float * length
x = array()
y = array()
status = dll.function(1, byref(x), byref(y))
Program crashes
Failed Attempt 5:
array = c_float * length
x = POINTER(array)()
y = POINTER(array)()
status = dll.function(1, x, y)
Null Pointer Error OR ArgumentError: expected LP_c_float instance instead of LP_c_float_Array_[length]
Failed Attempt 6:
x = (c_float*length)()
y = (c_float*length)()
a = cast(x, POINTER(c_float))
b = cast(y, POINTER(c_float))
status = dll.function(1, a, b)
Program crashes
What am I missing and why?
I believe the argtypes are correct. I am attempting to meet them properly, but there continues to be an issues. Do I need to "malloc" the memory somehow? (I'm sure I need to free after I get the data).
This is on Windows 7 with Python 2.7 32-bit.
I have looked through other similar issues and am not finding a solution. I am wondering if, at this point, I can blame the API for this issue.
python pointers ctypes
add a comment |
I am accessing an API and can't get the data returned. The two float pointers will point to an array of data. I must assume the API is working properly. A different function call provides a the length of the data I am retrieving. This values is length
down below when attempted.
C Header for Function
int function(int, float * data1, float * data2)
ctypes setup
dll.function.argtypes = (c_int, POINTER(c_float), POINTER(c_float))
dll.function.restypes = c_int
Failed Attempt 1:
x = c_float()
y = c_float()
status = dll.function(1, byref(x), byref(y))
Program crashes OR Access violation writing.
Failed Attempt 2:
x = POINTER(c_float)()
y = POINTER(c_float)()
status = dll.function(1, x, y)
Null Pointer Error
Failed Attempt 3:
dll.function.argtypes = (c_int, c_void_p, c_void_p)
x = c_void_p()
y = c_void_p()
status = dll.function(1, x, y)
Null Pointer Error
Failed Attempt 4:
array = c_float * length
x = array()
y = array()
status = dll.function(1, byref(x), byref(y))
Program crashes
Failed Attempt 5:
array = c_float * length
x = POINTER(array)()
y = POINTER(array)()
status = dll.function(1, x, y)
Null Pointer Error OR ArgumentError: expected LP_c_float instance instead of LP_c_float_Array_[length]
Failed Attempt 6:
x = (c_float*length)()
y = (c_float*length)()
a = cast(x, POINTER(c_float))
b = cast(y, POINTER(c_float))
status = dll.function(1, a, b)
Program crashes
What am I missing and why?
I believe the argtypes are correct. I am attempting to meet them properly, but there continues to be an issues. Do I need to "malloc" the memory somehow? (I'm sure I need to free after I get the data).
This is on Windows 7 with Python 2.7 32-bit.
I have looked through other similar issues and am not finding a solution. I am wondering if, at this point, I can blame the API for this issue.
python pointers ctypes
It is recommended to use cffi instead of ctypes. cffi is much more convenient.cffi.readthedocs.io/en/latest/overview.html A while ago I was also using ctypes, but people recommended to switch. And they were right, I would never tough ctypes again. :)
– Joe
Apr 26 '18 at 13:13
Examples on how to use pointers can be found at cffi.readthedocs.io/en/latest/…
– Joe
Apr 26 '18 at 13:15
Bothchar*
have the same length? They are allocated insidefunction
or should they be allocated by the caller (Python)?
– CristiFati
Apr 26 '18 at 16:23
Both float* are pointers to arrays. They will need to be allocated by the caller.
– houckrj
Apr 26 '18 at 17:11
add a comment |
I am accessing an API and can't get the data returned. The two float pointers will point to an array of data. I must assume the API is working properly. A different function call provides a the length of the data I am retrieving. This values is length
down below when attempted.
C Header for Function
int function(int, float * data1, float * data2)
ctypes setup
dll.function.argtypes = (c_int, POINTER(c_float), POINTER(c_float))
dll.function.restypes = c_int
Failed Attempt 1:
x = c_float()
y = c_float()
status = dll.function(1, byref(x), byref(y))
Program crashes OR Access violation writing.
Failed Attempt 2:
x = POINTER(c_float)()
y = POINTER(c_float)()
status = dll.function(1, x, y)
Null Pointer Error
Failed Attempt 3:
dll.function.argtypes = (c_int, c_void_p, c_void_p)
x = c_void_p()
y = c_void_p()
status = dll.function(1, x, y)
Null Pointer Error
Failed Attempt 4:
array = c_float * length
x = array()
y = array()
status = dll.function(1, byref(x), byref(y))
Program crashes
Failed Attempt 5:
array = c_float * length
x = POINTER(array)()
y = POINTER(array)()
status = dll.function(1, x, y)
Null Pointer Error OR ArgumentError: expected LP_c_float instance instead of LP_c_float_Array_[length]
Failed Attempt 6:
x = (c_float*length)()
y = (c_float*length)()
a = cast(x, POINTER(c_float))
b = cast(y, POINTER(c_float))
status = dll.function(1, a, b)
Program crashes
What am I missing and why?
I believe the argtypes are correct. I am attempting to meet them properly, but there continues to be an issues. Do I need to "malloc" the memory somehow? (I'm sure I need to free after I get the data).
This is on Windows 7 with Python 2.7 32-bit.
I have looked through other similar issues and am not finding a solution. I am wondering if, at this point, I can blame the API for this issue.
python pointers ctypes
I am accessing an API and can't get the data returned. The two float pointers will point to an array of data. I must assume the API is working properly. A different function call provides a the length of the data I am retrieving. This values is length
down below when attempted.
C Header for Function
int function(int, float * data1, float * data2)
ctypes setup
dll.function.argtypes = (c_int, POINTER(c_float), POINTER(c_float))
dll.function.restypes = c_int
Failed Attempt 1:
x = c_float()
y = c_float()
status = dll.function(1, byref(x), byref(y))
Program crashes OR Access violation writing.
Failed Attempt 2:
x = POINTER(c_float)()
y = POINTER(c_float)()
status = dll.function(1, x, y)
Null Pointer Error
Failed Attempt 3:
dll.function.argtypes = (c_int, c_void_p, c_void_p)
x = c_void_p()
y = c_void_p()
status = dll.function(1, x, y)
Null Pointer Error
Failed Attempt 4:
array = c_float * length
x = array()
y = array()
status = dll.function(1, byref(x), byref(y))
Program crashes
Failed Attempt 5:
array = c_float * length
x = POINTER(array)()
y = POINTER(array)()
status = dll.function(1, x, y)
Null Pointer Error OR ArgumentError: expected LP_c_float instance instead of LP_c_float_Array_[length]
Failed Attempt 6:
x = (c_float*length)()
y = (c_float*length)()
a = cast(x, POINTER(c_float))
b = cast(y, POINTER(c_float))
status = dll.function(1, a, b)
Program crashes
What am I missing and why?
I believe the argtypes are correct. I am attempting to meet them properly, but there continues to be an issues. Do I need to "malloc" the memory somehow? (I'm sure I need to free after I get the data).
This is on Windows 7 with Python 2.7 32-bit.
I have looked through other similar issues and am not finding a solution. I am wondering if, at this point, I can blame the API for this issue.
python pointers ctypes
python pointers ctypes
edited Jun 22 '18 at 12:07
CristiFati
15.2k72739
15.2k72739
asked Apr 26 '18 at 13:10
houckrjhouckrj
789
789
It is recommended to use cffi instead of ctypes. cffi is much more convenient.cffi.readthedocs.io/en/latest/overview.html A while ago I was also using ctypes, but people recommended to switch. And they were right, I would never tough ctypes again. :)
– Joe
Apr 26 '18 at 13:13
Examples on how to use pointers can be found at cffi.readthedocs.io/en/latest/…
– Joe
Apr 26 '18 at 13:15
Bothchar*
have the same length? They are allocated insidefunction
or should they be allocated by the caller (Python)?
– CristiFati
Apr 26 '18 at 16:23
Both float* are pointers to arrays. They will need to be allocated by the caller.
– houckrj
Apr 26 '18 at 17:11
add a comment |
It is recommended to use cffi instead of ctypes. cffi is much more convenient.cffi.readthedocs.io/en/latest/overview.html A while ago I was also using ctypes, but people recommended to switch. And they were right, I would never tough ctypes again. :)
– Joe
Apr 26 '18 at 13:13
Examples on how to use pointers can be found at cffi.readthedocs.io/en/latest/…
– Joe
Apr 26 '18 at 13:15
Bothchar*
have the same length? They are allocated insidefunction
or should they be allocated by the caller (Python)?
– CristiFati
Apr 26 '18 at 16:23
Both float* are pointers to arrays. They will need to be allocated by the caller.
– houckrj
Apr 26 '18 at 17:11
It is recommended to use cffi instead of ctypes. cffi is much more convenient.cffi.readthedocs.io/en/latest/overview.html A while ago I was also using ctypes, but people recommended to switch. And they were right, I would never tough ctypes again. :)
– Joe
Apr 26 '18 at 13:13
It is recommended to use cffi instead of ctypes. cffi is much more convenient.cffi.readthedocs.io/en/latest/overview.html A while ago I was also using ctypes, but people recommended to switch. And they were right, I would never tough ctypes again. :)
– Joe
Apr 26 '18 at 13:13
Examples on how to use pointers can be found at cffi.readthedocs.io/en/latest/…
– Joe
Apr 26 '18 at 13:15
Examples on how to use pointers can be found at cffi.readthedocs.io/en/latest/…
– Joe
Apr 26 '18 at 13:15
Both
char*
have the same length? They are allocated inside function
or should they be allocated by the caller (Python)?– CristiFati
Apr 26 '18 at 16:23
Both
char*
have the same length? They are allocated inside function
or should they be allocated by the caller (Python)?– CristiFati
Apr 26 '18 at 16:23
Both float* are pointers to arrays. They will need to be allocated by the caller.
– houckrj
Apr 26 '18 at 17:11
Both float* are pointers to arrays. They will need to be allocated by the caller.
– houckrj
Apr 26 '18 at 17:11
add a comment |
2 Answers
2
active
oldest
votes
Dealing with pointers and arrays is explained in [Python 3]: Type conversions.
I prepared a dummy example for you.
main.c:
#if defined(_WIN32)
# define DECLSPEC_DLLEXPORT __declspec(dllexport)
#else
# define DECLSPEC_DLLEXPORT
#endif
static int kSize = 5;
DECLSPEC_DLLEXPORT int size()
return kSize;
DECLSPEC_DLLEXPORT int function(int dummy, float *data1, float *data2)
for (int i = 0; i < kSize; i++)
data1[i] = dummy * i;
data2[i] = -dummy * (i + 1);
return 0;
code.py:
#!/usr/bin/env python
import sys
import ctypes
c_float_p = ctypes.POINTER(ctypes.c_float)
def main():
dll_dll = ctypes.CDLL("./dll.so")
size_func = dll_dll.size
size_func.argtypes = []
size_func.restype = ctypes.c_int
function_func = dll_dll.function
function_func.argtypes = [ctypes.c_int, c_float_p, c_float_p]
function_func.restype = ctypes.c_int
size = size_func()
print(size)
data1 = (ctypes.c_float * size)()
data2 = (ctypes.c_float * size)()
res = function_func(1, ctypes.cast(data1, c_float_p), ctypes.cast(data2, c_float_p))
for i in range(size):
print(data1[i], data2[i])
if __name__ == "__main__":
print("Python :s on :sn".format(sys.version, sys.platform))
main()
Notes:
- The C part tries to mimic what your .dll does (or at least what I understood):
size - gets the arrays sizes
function - populates the arrays (till their size - assuming that they were properly allocated by the caller)
Python part is straightforward:- Load the .dll
- Define argtypes and restype (in your code it's restype's) for the 2 functions (for size_func not necessary)
- Get the lengths
- Initialize the arrays
- Pass them to function_func using
ctypes.cast
- Load the .dll
Output (on Lnx, as building the C code is much simpler, but works on Win as well):
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> gcc -shared -o dll.so main.c
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> python3 code.py
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
5
0.0 -1.0
1.0 -2.0
2.0 -3.0
3.0 -4.0
4.0 -5.0
Did this answer your question?
– CristiFati
Apr 28 '18 at 4:33
Just accepted. I got pulled away to something else for a week. Thank you.
– houckrj
May 8 '18 at 20:10
You're welcome! :)
– CristiFati
May 8 '18 at 20:29
add a comment |
It really depends on what you are doing with these float pointers.
If you are trying to traverse it, i.e.
for(int i = 0; i < size; i++)
printf("%fn%, data1[i])
then for sure this is problematic as no array was allocated. You simply passed a pointer pointing to a float. That is all.
You need to first allocate that memory. To this end Attempt 4 looks like the more promising, but I suspect you have a problem inside your C function leading to the crash.
Difficult to say without seeing the implementation of that function.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f50043861%2fpython-ctypes-passing-pointer-for-data%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Dealing with pointers and arrays is explained in [Python 3]: Type conversions.
I prepared a dummy example for you.
main.c:
#if defined(_WIN32)
# define DECLSPEC_DLLEXPORT __declspec(dllexport)
#else
# define DECLSPEC_DLLEXPORT
#endif
static int kSize = 5;
DECLSPEC_DLLEXPORT int size()
return kSize;
DECLSPEC_DLLEXPORT int function(int dummy, float *data1, float *data2)
for (int i = 0; i < kSize; i++)
data1[i] = dummy * i;
data2[i] = -dummy * (i + 1);
return 0;
code.py:
#!/usr/bin/env python
import sys
import ctypes
c_float_p = ctypes.POINTER(ctypes.c_float)
def main():
dll_dll = ctypes.CDLL("./dll.so")
size_func = dll_dll.size
size_func.argtypes = []
size_func.restype = ctypes.c_int
function_func = dll_dll.function
function_func.argtypes = [ctypes.c_int, c_float_p, c_float_p]
function_func.restype = ctypes.c_int
size = size_func()
print(size)
data1 = (ctypes.c_float * size)()
data2 = (ctypes.c_float * size)()
res = function_func(1, ctypes.cast(data1, c_float_p), ctypes.cast(data2, c_float_p))
for i in range(size):
print(data1[i], data2[i])
if __name__ == "__main__":
print("Python :s on :sn".format(sys.version, sys.platform))
main()
Notes:
- The C part tries to mimic what your .dll does (or at least what I understood):
size - gets the arrays sizes
function - populates the arrays (till their size - assuming that they were properly allocated by the caller)
Python part is straightforward:- Load the .dll
- Define argtypes and restype (in your code it's restype's) for the 2 functions (for size_func not necessary)
- Get the lengths
- Initialize the arrays
- Pass them to function_func using
ctypes.cast
- Load the .dll
Output (on Lnx, as building the C code is much simpler, but works on Win as well):
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> gcc -shared -o dll.so main.c
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> python3 code.py
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
5
0.0 -1.0
1.0 -2.0
2.0 -3.0
3.0 -4.0
4.0 -5.0
Did this answer your question?
– CristiFati
Apr 28 '18 at 4:33
Just accepted. I got pulled away to something else for a week. Thank you.
– houckrj
May 8 '18 at 20:10
You're welcome! :)
– CristiFati
May 8 '18 at 20:29
add a comment |
Dealing with pointers and arrays is explained in [Python 3]: Type conversions.
I prepared a dummy example for you.
main.c:
#if defined(_WIN32)
# define DECLSPEC_DLLEXPORT __declspec(dllexport)
#else
# define DECLSPEC_DLLEXPORT
#endif
static int kSize = 5;
DECLSPEC_DLLEXPORT int size()
return kSize;
DECLSPEC_DLLEXPORT int function(int dummy, float *data1, float *data2)
for (int i = 0; i < kSize; i++)
data1[i] = dummy * i;
data2[i] = -dummy * (i + 1);
return 0;
code.py:
#!/usr/bin/env python
import sys
import ctypes
c_float_p = ctypes.POINTER(ctypes.c_float)
def main():
dll_dll = ctypes.CDLL("./dll.so")
size_func = dll_dll.size
size_func.argtypes = []
size_func.restype = ctypes.c_int
function_func = dll_dll.function
function_func.argtypes = [ctypes.c_int, c_float_p, c_float_p]
function_func.restype = ctypes.c_int
size = size_func()
print(size)
data1 = (ctypes.c_float * size)()
data2 = (ctypes.c_float * size)()
res = function_func(1, ctypes.cast(data1, c_float_p), ctypes.cast(data2, c_float_p))
for i in range(size):
print(data1[i], data2[i])
if __name__ == "__main__":
print("Python :s on :sn".format(sys.version, sys.platform))
main()
Notes:
- The C part tries to mimic what your .dll does (or at least what I understood):
size - gets the arrays sizes
function - populates the arrays (till their size - assuming that they were properly allocated by the caller)
Python part is straightforward:- Load the .dll
- Define argtypes and restype (in your code it's restype's) for the 2 functions (for size_func not necessary)
- Get the lengths
- Initialize the arrays
- Pass them to function_func using
ctypes.cast
- Load the .dll
Output (on Lnx, as building the C code is much simpler, but works on Win as well):
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> gcc -shared -o dll.so main.c
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> python3 code.py
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
5
0.0 -1.0
1.0 -2.0
2.0 -3.0
3.0 -4.0
4.0 -5.0
Did this answer your question?
– CristiFati
Apr 28 '18 at 4:33
Just accepted. I got pulled away to something else for a week. Thank you.
– houckrj
May 8 '18 at 20:10
You're welcome! :)
– CristiFati
May 8 '18 at 20:29
add a comment |
Dealing with pointers and arrays is explained in [Python 3]: Type conversions.
I prepared a dummy example for you.
main.c:
#if defined(_WIN32)
# define DECLSPEC_DLLEXPORT __declspec(dllexport)
#else
# define DECLSPEC_DLLEXPORT
#endif
static int kSize = 5;
DECLSPEC_DLLEXPORT int size()
return kSize;
DECLSPEC_DLLEXPORT int function(int dummy, float *data1, float *data2)
for (int i = 0; i < kSize; i++)
data1[i] = dummy * i;
data2[i] = -dummy * (i + 1);
return 0;
code.py:
#!/usr/bin/env python
import sys
import ctypes
c_float_p = ctypes.POINTER(ctypes.c_float)
def main():
dll_dll = ctypes.CDLL("./dll.so")
size_func = dll_dll.size
size_func.argtypes = []
size_func.restype = ctypes.c_int
function_func = dll_dll.function
function_func.argtypes = [ctypes.c_int, c_float_p, c_float_p]
function_func.restype = ctypes.c_int
size = size_func()
print(size)
data1 = (ctypes.c_float * size)()
data2 = (ctypes.c_float * size)()
res = function_func(1, ctypes.cast(data1, c_float_p), ctypes.cast(data2, c_float_p))
for i in range(size):
print(data1[i], data2[i])
if __name__ == "__main__":
print("Python :s on :sn".format(sys.version, sys.platform))
main()
Notes:
- The C part tries to mimic what your .dll does (or at least what I understood):
size - gets the arrays sizes
function - populates the arrays (till their size - assuming that they were properly allocated by the caller)
Python part is straightforward:- Load the .dll
- Define argtypes and restype (in your code it's restype's) for the 2 functions (for size_func not necessary)
- Get the lengths
- Initialize the arrays
- Pass them to function_func using
ctypes.cast
- Load the .dll
Output (on Lnx, as building the C code is much simpler, but works on Win as well):
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> gcc -shared -o dll.so main.c
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> python3 code.py
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
5
0.0 -1.0
1.0 -2.0
2.0 -3.0
3.0 -4.0
4.0 -5.0
Dealing with pointers and arrays is explained in [Python 3]: Type conversions.
I prepared a dummy example for you.
main.c:
#if defined(_WIN32)
# define DECLSPEC_DLLEXPORT __declspec(dllexport)
#else
# define DECLSPEC_DLLEXPORT
#endif
static int kSize = 5;
DECLSPEC_DLLEXPORT int size()
return kSize;
DECLSPEC_DLLEXPORT int function(int dummy, float *data1, float *data2)
for (int i = 0; i < kSize; i++)
data1[i] = dummy * i;
data2[i] = -dummy * (i + 1);
return 0;
code.py:
#!/usr/bin/env python
import sys
import ctypes
c_float_p = ctypes.POINTER(ctypes.c_float)
def main():
dll_dll = ctypes.CDLL("./dll.so")
size_func = dll_dll.size
size_func.argtypes = []
size_func.restype = ctypes.c_int
function_func = dll_dll.function
function_func.argtypes = [ctypes.c_int, c_float_p, c_float_p]
function_func.restype = ctypes.c_int
size = size_func()
print(size)
data1 = (ctypes.c_float * size)()
data2 = (ctypes.c_float * size)()
res = function_func(1, ctypes.cast(data1, c_float_p), ctypes.cast(data2, c_float_p))
for i in range(size):
print(data1[i], data2[i])
if __name__ == "__main__":
print("Python :s on :sn".format(sys.version, sys.platform))
main()
Notes:
- The C part tries to mimic what your .dll does (or at least what I understood):
size - gets the arrays sizes
function - populates the arrays (till their size - assuming that they were properly allocated by the caller)
Python part is straightforward:- Load the .dll
- Define argtypes and restype (in your code it's restype's) for the 2 functions (for size_func not necessary)
- Get the lengths
- Initialize the arrays
- Pass them to function_func using
ctypes.cast
- Load the .dll
Output (on Lnx, as building the C code is much simpler, but works on Win as well):
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> gcc -shared -o dll.so main.c
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> python3 code.py
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
5
0.0 -1.0
1.0 -2.0
2.0 -3.0
3.0 -4.0
4.0 -5.0
edited Mar 9 at 2:33
answered Apr 26 '18 at 17:15
CristiFatiCristiFati
15.2k72739
15.2k72739
Did this answer your question?
– CristiFati
Apr 28 '18 at 4:33
Just accepted. I got pulled away to something else for a week. Thank you.
– houckrj
May 8 '18 at 20:10
You're welcome! :)
– CristiFati
May 8 '18 at 20:29
add a comment |
Did this answer your question?
– CristiFati
Apr 28 '18 at 4:33
Just accepted. I got pulled away to something else for a week. Thank you.
– houckrj
May 8 '18 at 20:10
You're welcome! :)
– CristiFati
May 8 '18 at 20:29
Did this answer your question?
– CristiFati
Apr 28 '18 at 4:33
Did this answer your question?
– CristiFati
Apr 28 '18 at 4:33
Just accepted. I got pulled away to something else for a week. Thank you.
– houckrj
May 8 '18 at 20:10
Just accepted. I got pulled away to something else for a week. Thank you.
– houckrj
May 8 '18 at 20:10
You're welcome! :)
– CristiFati
May 8 '18 at 20:29
You're welcome! :)
– CristiFati
May 8 '18 at 20:29
add a comment |
It really depends on what you are doing with these float pointers.
If you are trying to traverse it, i.e.
for(int i = 0; i < size; i++)
printf("%fn%, data1[i])
then for sure this is problematic as no array was allocated. You simply passed a pointer pointing to a float. That is all.
You need to first allocate that memory. To this end Attempt 4 looks like the more promising, but I suspect you have a problem inside your C function leading to the crash.
Difficult to say without seeing the implementation of that function.
add a comment |
It really depends on what you are doing with these float pointers.
If you are trying to traverse it, i.e.
for(int i = 0; i < size; i++)
printf("%fn%, data1[i])
then for sure this is problematic as no array was allocated. You simply passed a pointer pointing to a float. That is all.
You need to first allocate that memory. To this end Attempt 4 looks like the more promising, but I suspect you have a problem inside your C function leading to the crash.
Difficult to say without seeing the implementation of that function.
add a comment |
It really depends on what you are doing with these float pointers.
If you are trying to traverse it, i.e.
for(int i = 0; i < size; i++)
printf("%fn%, data1[i])
then for sure this is problematic as no array was allocated. You simply passed a pointer pointing to a float. That is all.
You need to first allocate that memory. To this end Attempt 4 looks like the more promising, but I suspect you have a problem inside your C function leading to the crash.
Difficult to say without seeing the implementation of that function.
It really depends on what you are doing with these float pointers.
If you are trying to traverse it, i.e.
for(int i = 0; i < size; i++)
printf("%fn%, data1[i])
then for sure this is problematic as no array was allocated. You simply passed a pointer pointing to a float. That is all.
You need to first allocate that memory. To this end Attempt 4 looks like the more promising, but I suspect you have a problem inside your C function leading to the crash.
Difficult to say without seeing the implementation of that function.
answered Apr 26 '18 at 13:22
Al WldAl Wld
384111
384111
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f50043861%2fpython-ctypes-passing-pointer-for-data%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
It is recommended to use cffi instead of ctypes. cffi is much more convenient.cffi.readthedocs.io/en/latest/overview.html A while ago I was also using ctypes, but people recommended to switch. And they were right, I would never tough ctypes again. :)
– Joe
Apr 26 '18 at 13:13
Examples on how to use pointers can be found at cffi.readthedocs.io/en/latest/…
– Joe
Apr 26 '18 at 13:15
Both
char*
have the same length? They are allocated insidefunction
or should they be allocated by the caller (Python)?– CristiFati
Apr 26 '18 at 16:23
Both float* are pointers to arrays. They will need to be allocated by the caller.
– houckrj
Apr 26 '18 at 17:11