I have a very small library in Lazarus and I'm unable to use it with ctypes on my Mac. I don't really understand what I'm doing incorrectly, and I was hoping someone can point me in the right direction.
This is the code that I have in Lazarus. When compiling on a Linux machine (Ubuntu VM), everything works fine. I can create a Linux .so file, and using ctypes, I can call into the shared library.
library project1;
{$mode delphi}{$H+}
{$IFDEF Darwin}
{$linkframework CoreFoundation}
{$linkframework Carbon}
{$ENDIF}
function SubStr(CString: PChar;FromPos,ToPos: Longint): PChar; cdecl;
var
Length: Integer;
begin
Length := StrLen(CString);
SubStr := CString + Length;
if (FromPos > 0) and (ToPos >= FromPos) then
begin
if Length >= FromPos then
SubStr := CString + FromPos - 1;
if Length > ToPos then
CString[ToPos] := #0;
end;
end;
exports
SubStr;
end.
The Python code for this is below.
import ctypes
lib = ctypes.CDLL('./libproject1.so')
lib.SubStr.argtypes = (ctypes.c_char_p, ctypes.c_int64, ctypes.c_int64)
lib.SubStr.restype = ctypes.c_char_p
lib.SubStr('HelloWorld', 1, 5)
# The output is 'Hello' as expected
However, when I test the same thing on my Mac, I get the following error.
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
<ipython-input-44-37971b70da86> in <module>()
1 import ctypes
2
----> 3 ctypes.CDLL('./libproject1.dylib')
/Users/$USER/miniconda2/lib/python2.7/ctypes/__init__.pyc in __init__(self, name, mode, handle, use_errno, use_last_error)
360
361 if handle is None:
--> 362 self._handle = _dlopen(self._name, mode)
363 else:
364 self._handle = handle
OSError: dlopen(./libproject1.dylib, 6): no suitable image found. Did find:
./libproject1.dylib: mach-o, but wrong architecture
I've created a new project on the mac and tried the same thing to no avail.
On using lipo on this dylib, I get the following output.
$ lipo -info libproject1.dylib
Non-fat file: libproject1.dylib is architecture: i386
I believe this is what I'm supposed to get. Anyone have any suggestions on how to go about figuring this out?
Miniconda is evidently a 64-bit version of Python. Your library is 32 bits. (An architecture of i386 is 32-bit; you should see x86_64 for a 64-bit library.) Thus, Python correctly reports "wrong architecture."
Recompile your library as a 64-bit binary and try again.