通过 Firemonkey 访问第三方 Mac API
Accessing a third party Mac API through Firemonkey
我有一个硬件制造商提供的 SDK,它提供 Windows 和 Mac APIs。在 Windows 中,这是一个标准的 COM DLL。在 Mac 上,它在图书馆的捆绑包中。有人可以告诉我如何从 Firemonkey 应用程序访问功能的起点吗?
Plist 文件提到
<key>CFBundleExecutable</key>
和
<key>CFBundlePackageType</key>
<string>BNDL</string>
并且捆绑包包含一个没有文件扩展名但 'kind' 为 'Unix executable'
的文件
包含文件包含以下(简化的)代码,用于在 XCode 中从 C++ 访问 API :
typedef IDiscovery* (*CreateDiscoveryFunc)(void);
static pthread_once_t gOnceControl = PTHREAD_ONCE_INIT;
static CreateDiscoveryFunc gCreateDiscoveryFunc = NULL;
static void InitAPI (void)
{
bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kAPI_BundlePath), kCFURLPOSIXPathStyle, true);
if (bundleURL != NULL)
{
gBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL);
if (gBundleRef != NULL)
{
gCreateDiscoveryFunc = (CreateDiscoveryFunc)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("GetDiscoveryInstance"));
}
CFRelease(bundleURL);
}
}
IDiscovery* CreateDiscoveryInstance (void)
{
pthread_once(&gOnceControl, InitAPI);
if (gCreateDiscoveryFunc == NULL)
return NULL;
return gCreateDiscoveryFunc();
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
mDiscovery = NULL;
mDevice = NULL;
mDiscovery = CreateDiscoveryInstance();
if (! mDiscovery)
{
/* Show an alert to say the API may not be installed, and quit program */
}
NSString* address = [mAddressTextField stringValue];
ConnectToFailure failReason;
HRESULT hr = mDiscovery->ConnectTo((CFStringRef)address, &mDevice, &failReason);
}
如果我能获得 mDevice 对象,那么我应该能够获得使用 API.
所需的所有其他对象
这 'Unix executable' 会不会只是一个 DYLIB?
运行 file path/to/file
在那个二进制文件上,它应该告诉你它是什么。
如果显示 Mach-O 64-bit bundle
,则您必须使用 dlopen()
和 dlsym()
来访问其导出的函数。
如果它说 Mach-O 64-bit dynamically linked shared library
,那么它是一个共享库,它可以在编译时被 linked 反对。
这里要注意的是,您的二进制文件没有扩展名这一事实让我认为它是“框架”的形式。也就是说,它将具有共享库的格式,但路径为 some/path/SomeName.framework/Versions/Current/SomeName
。如果是这样,您可以 link 使用 -F some/path -framework SomeName
.
来反对它
如果二进制文件不是框架形式,只是一个没有后缀的共享库,那么 link 使用它会有些痛苦,因为 clang/ld64 只真正接受lib<string>.dylib
或lib<string>.tbd
。重命名库会使它的安装名称无效,但你需要它让编译器工具链找到它。
如果您真的处于这种情况,那么最简单的解决方法是从您的 dylib 创建一个待定文件(这只是一个文本文件,列出了 dylib 的所有 linking 信息,并且可以代替它用于动态linking)。为此,您将使用:
xcrun tapi stubify -o some/path/libsomething.tbd path/to/binary
然后当 linking 时,您将使用 -L some/path -l something
。
我有一个硬件制造商提供的 SDK,它提供 Windows 和 Mac APIs。在 Windows 中,这是一个标准的 COM DLL。在 Mac 上,它在图书馆的捆绑包中。有人可以告诉我如何从 Firemonkey 应用程序访问功能的起点吗?
Plist 文件提到
<key>CFBundleExecutable</key>
和
<key>CFBundlePackageType</key>
<string>BNDL</string>
并且捆绑包包含一个没有文件扩展名但 'kind' 为 'Unix executable'
的文件包含文件包含以下(简化的)代码,用于在 XCode 中从 C++ 访问 API :
typedef IDiscovery* (*CreateDiscoveryFunc)(void);
static pthread_once_t gOnceControl = PTHREAD_ONCE_INIT;
static CreateDiscoveryFunc gCreateDiscoveryFunc = NULL;
static void InitAPI (void)
{
bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kAPI_BundlePath), kCFURLPOSIXPathStyle, true);
if (bundleURL != NULL)
{
gBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL);
if (gBundleRef != NULL)
{
gCreateDiscoveryFunc = (CreateDiscoveryFunc)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("GetDiscoveryInstance"));
}
CFRelease(bundleURL);
}
}
IDiscovery* CreateDiscoveryInstance (void)
{
pthread_once(&gOnceControl, InitAPI);
if (gCreateDiscoveryFunc == NULL)
return NULL;
return gCreateDiscoveryFunc();
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
mDiscovery = NULL;
mDevice = NULL;
mDiscovery = CreateDiscoveryInstance();
if (! mDiscovery)
{
/* Show an alert to say the API may not be installed, and quit program */
}
NSString* address = [mAddressTextField stringValue];
ConnectToFailure failReason;
HRESULT hr = mDiscovery->ConnectTo((CFStringRef)address, &mDevice, &failReason);
}
如果我能获得 mDevice 对象,那么我应该能够获得使用 API.
所需的所有其他对象这 'Unix executable' 会不会只是一个 DYLIB?
运行 file path/to/file
在那个二进制文件上,它应该告诉你它是什么。
如果显示 Mach-O 64-bit bundle
,则您必须使用 dlopen()
和 dlsym()
来访问其导出的函数。
如果它说 Mach-O 64-bit dynamically linked shared library
,那么它是一个共享库,它可以在编译时被 linked 反对。
这里要注意的是,您的二进制文件没有扩展名这一事实让我认为它是“框架”的形式。也就是说,它将具有共享库的格式,但路径为 some/path/SomeName.framework/Versions/Current/SomeName
。如果是这样,您可以 link 使用 -F some/path -framework SomeName
.
如果二进制文件不是框架形式,只是一个没有后缀的共享库,那么 link 使用它会有些痛苦,因为 clang/ld64 只真正接受lib<string>.dylib
或lib<string>.tbd
。重命名库会使它的安装名称无效,但你需要它让编译器工具链找到它。
如果您真的处于这种情况,那么最简单的解决方法是从您的 dylib 创建一个待定文件(这只是一个文本文件,列出了 dylib 的所有 linking 信息,并且可以代替它用于动态linking)。为此,您将使用:
xcrun tapi stubify -o some/path/libsomething.tbd path/to/binary
然后当 linking 时,您将使用 -L some/path -l something
。