英文:
Mix C++ and Objective-C code using CMake and get C++ executable
问题
可以使用Objective-C和Cocoa库构建一个独立的库,并为其创建一个公共接口,以便在C++项目中使用。这是完全可能的,而且你的项目已经朝着正确的方向迈出了一些重要步骤。
在你的项目中,你有一个名为WindowBuilderObjCLib
的Objective-C++库,该库使用了Cocoa库,并且已经为其创建了一个公共接口src/Draw/WindowBuilder/WindowBuilder.h
。这个库的公共接口允许你从C++代码中调用Objective-C++的功能。
然而,要解决你遇到的编译错误,你需要确保在C++代码中正确包含Objective-C++库的头文件,并正确链接Objective-C++库。在你的main.cpp
文件中,确保你正确包含了库的头文件,例如:
#include <Draw/WindowBuilder/WindowBuilder.h>
然后,在CMakeLists.txt中,确保你的Engine
目标链接到WindowBuilderObjCLib
:
target_link_libraries(Engine PRIVATE
WindowBuilderObjCLib
DrawLib
UtilsLib
OpenGL::GL
${FOUNDATION_FRAMEWORK}
)
这样做后,你的C++代码应该能够正确调用Objective-C++库中的函数,并且不再出现编译错误。
总之,是可以构建一个包含Objective-C代码的独立库,并在C++项目中使用的。只需确保正确设置包含路径和链接库,以便在C++代码中使用Objective-C部分。
英文:
The Idea
I'm trying to implement a game engine in C++.
I'm using macOS for development (arm-64 architecture). I want to create a window using Foundation framework.
CMakeLists.txt utilizes C++ and Objective-C languages, and I want to build a library containing only Objective-C code and then use this library in my C++ code (probably including the header). The end result should be a C++ executable.
The Project Structure
[src]
├── [Draw]
├── Window.cpp
├── Window.h
└── [WindowBuilder]
├── WindowBuilder.cpp
├── WindowBuilder.h
└── [macOS]
├── WindowBuilderObjC.h
└── WindowBuilderObjC.mm
├── [Utils]
└── Size.h
├── main.cpp
└── CMakeLists.txt
The Source Code
src/Draw/Window.h
#include <iostream>
#include <Utils/Size.h>
#include "WindowBuilder/WindowBuilder.h"
#pragma once
namespace Draw
{
class Window
{
private:
bool _isPresented;
Utils::Size _size = Utils::Size(0, 0);
WindowBuilder::WindowBuilder *_builder;
Window();
~Window() = default;
public:
// Public static member function to access the singleton instance
static Window &Instance()
{
// Guaranteed to be initialized once
static Window instance;
return instance;
}
// Delete the copy constructor and assignment operator
Window(const Window &) = delete;
Window &operator=(const Window &) = delete;
void SetSize(Utils::Size size);
void DrawWindow();
};
}
src/Draw/Window.cpp
#include "Window.h"
namespace Draw
{
Window::Window()
{
_builder = &WindowBuilder::WindowBuilder::Instance();
}
void Window::SetSize(Utils::Size size)
{
_size = size;
}
void Window::DrawWindow()
{
std::cout << "Draw window with size: [" << _size.GetWidth() << ":" << _size.GetHeight() << "]" << std::endl;
_builder->BuildWindow(_size);
}
}
src/WindowBuilder/WindowBuilder.h
// General
#include <iostream>
// Internal
#include <Utils/Size.h>
#include <Draw/WindowBuilder/macOS/WindowBuilderObjC.h>
#pragma once
namespace WindowBuilder
{
class WindowBuilder
{
private:
bool _isPresented;
WindowBuilder() = default;
~WindowBuilder() = default;
public:
static WindowBuilder &Instance()
{
// Guaranteed to be initialized once
static WindowBuilder instance;
return instance;
}
// Delete the copy constructor and assignment operator
WindowBuilder(const WindowBuilder &) = delete;
WindowBuilder &operator=(const WindowBuilder &) = delete;
void BuildWindow(Utils::Size size);
};
}
src/WindowBuilder/WindowBuilder.cpp
#include "WindowBuilder.h"
namespace WindowBuilder
{
void WindowBuilder::BuildWindow(Utils::Size size)
{
buildWindowWithSize(size);
}
}
src/Draw/WindowBuilder/macOS/WindowBuilderObjC.h
#import <Cocoa/Cocoa.h>
#import "Utils/Size.h"
@interface WindowBuilderObjC : NSObject
- (void)buildWindowWithSize:(Utils::Size)size;
@end
@interface WindowDelegate : NSObject <NSWindowDelegate>
@end
@implementation WindowDelegate
- (BOOL)windowShouldClose:(id)sender
{
[NSApp terminate:nil];
return YES;
}
@end
src/Draw/WindowBuilder/macOS/WindowBuilderObjC.mm
#import "WindowBuilderObjC.h"
@implementation WindowBuilderObjC
- (void)buildWindowWithSize:(Utils::Size)size
{
@autoreleasepool
{
[NSApplication sharedApplication];
NSRect frame = NSMakeRect(0, 0, 800, 600);
NSUInteger style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable;
NSWindow *window = [[NSWindow alloc] initWithContentRect:frame styleMask:style backing:NSBackingStoreBuffered defer:NO];
[window setTitle:@"My Window"];
[window center];
WindowDelegate *delegate = [[WindowDelegate alloc] init];
[window setDelegate:delegate];
[window makeKeyAndOrderFront:nil];
[NSApp run];
}
}
@end
src/main.cpp
#include <iostream>
#include <Draw/Window.h>
#include <Utils/Size.h>
int main()
{
std::cout << "Hello World" << std::endl;
Utils::Size size(600, 800);
auto &window = Draw::Window::Instance();
window.SetSize(size);
window.DrawWindow();
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(GameEngine LANGUAGES CXX OBJC OBJCXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# enable_language(OBJC)
# enable_language(OBJCXX)
add_executable(Engine src/main.cpp)
add_library(UtilsLib SHARED
src/Utils/Size.h
)
set_target_properties(UtilsLib PROPERTIES LINKER_LANGUAGE CXX)
add_library(WindowBuilderObjCLib SHARED
src/Draw/WindowBuilder/macOS/WindowBuilderObjC.h
src/Draw/WindowBuilder/macOS/WindowBuilderObjC.mm
)
target_include_directories(WindowBuilderObjCLib
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/Draw/WindowBuilder/macOS
)
target_link_libraries(WindowBuilderObjCLib
PRIVATE "-framework Cocoa"
PRIVATE "-framework Foundation"
PRIVATE "-framework AppKit"
)
# Set the language for the library to Objective-C++
set_target_properties(WindowBuilderObjCLib PROPERTIES
LINKER_LANGUAGE "OBJCXX"
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES YES
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_WEAK YES
)
add_library(DrawLib STATIC
src/Draw/Window.h
src/Draw/Window.cpp
)
target_sources(DrawLib
PRIVATE
src/Draw/WindowBuilder/WindowBuilder.h
src/Draw/WindowBuilder/WindowBuilder.cpp
)
target_sources(DrawLib
PUBLIC
src/Draw/Window.h
src/Draw/Window.cpp
)
set_target_properties(DrawLib PROPERTIES LINKER_LANGUAGE CXX)
find_library(FOUNDATION_FRAMEWORK Foundation)
# Link against required frameworks and libraries
target_link_libraries(DrawLib
PRIVATE ${FOUNDATION_FRAMEWORK}
"-framework AppKit"
"-framework CoreGraphics"
"-lobjc"
)
find_package(OpenGL REQUIRED COMPONENTS OpenGL)
include_directories(${CMAKE_SOURCE_DIR}/src)
add_subdirectory(src/Draw/WindowBuilder/macOS)
# Link the DrawLib and UtilsLib targets to the Engine target
target_link_libraries(Engine PRIVATE
WindowBuilderObjCLib
DrawLib
UtilsLib
OpenGL::GL
${FOUNDATION_FRAMEWORK}
)
The Error
Seems like when I include Window.h into main.cpp, the compiler looks for symbols in Cocoa/Cocoa.h file and finds Objective-C symbols instead of C++.
The error is following:
[build] In file included from /Users/user/MySource/GameEngine_Vulkan/src/Draw/Window.cpp:1:
[build] In file included from /Users/user/MySource/GameEngine_Vulkan/src/Draw/Window.h:4:
[build] In file included from /Users/user/MySource/GameEngine_Vulkan/src/Draw/WindowBuilder/WindowBuilder.h:6:
[build] In file included from /Users/user/MySource/GameEngine_Vulkan/src/Draw/WindowBuilder/macOS/WindowBuilderObjC.h:1:
[build] In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Cocoa.framework/Headers/Cocoa.h:12:
[build] In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:8:
[build] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:601:1: error: expected unqualified-id
[build] @class NSString, Protocol;
[build] In file included from /Users/user/MySource/GameEngine_Vulkan/src/Draw/WindowBuilder/WindowBuilder.cpp:1:
[build] In file included from /Users/user/MySource/GameEngine_Vulkan/src/Draw/WindowBuilder/WindowBuilder.h:6:
[build] ^
[build] In file included from /Users/user/MySource/GameEngine_Vulkan/src/Draw/WindowBuilder/macOS/WindowBuilderObjC.h:1:
[build] In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Cocoa.framework/Headers/Cocoa.h:12:
[build] In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:8:
[build] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:601:1: error: expected unqualified-id
[build] @class NSString, Protocol;
[build] ^
[build] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:603:9: error: unknown type name 'NSString'
[build] typedef NSString * NSExceptionName NS_TYPED_EXTENSIBLE_ENUM;
[build] ^
[build] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:603:9: error: unknown type name 'NSString'
[build] typedef NSString * NSExceptionName NS_TYPED_EXTENSIBLE_ENUM;
[build] ^
[build] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:604:9: error: unknown type name 'NSString'
[build] typedef NSString * NSRunLoopMode NS_TYPED_EXTENSIBLE_ENUM;
[build] ^
[build] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:604:9: error: unknown type name 'NSString'
[build] typedef NSString * NSRunLoopMode NS_TYPED_EXTENSIBLE_ENUM;
[build] ^
[build] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:606:19: error: unknown type name 'NSString'
[build] FOUNDATION_EXPORT NSString *NSStringFromSelector(SEL aSelector);
[build] ^
[build] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:606:19: error: unknown type name 'NSString'
[build] FOUNDATION_EXPORT NSString *NSStringFromSelector(SEL aSelector);
[build] ^
...
The Question
Can I build a standalone library using Objective-C with Cocoa lib included (probably) and that it will have a public interface, so that I can use it in C++ project?
答案1
得分: 0
以下是翻译好的部分:
1. 在Objective-C中编写代码,提供所需的功能(在我的情况下,创建macOS窗口):
WindowBuilderObjC.h
#ifndef WindowBuilderObjC_h
#define WindowBuilderObjC_h
#import <Cocoa/Cocoa.h>
@interface WindowBuilderObjC : NSObject
- (void)buildWindowWithWidth:(int)width height:(int)height;
@end
@interface WindowDelegate : NSObject <NSWindowDelegate>
@end
#endif /* WindowBuilderObjC_h */
WindowBuilderObjC.mm
#import "WindowBuilderObjC.h"
@implementation WindowBuilderObjC
- (void)buildWindowWithWidth:(int)width height:(int)height
{
@autoreleasepool
{
[NSApplication sharedApplication];
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
NSRect frame = NSMakeRect(0, 0, 800, 600);
NSUInteger style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable;
NSWindow *window = [[NSWindow alloc] initWithContentRect:frame styleMask:style backing:NSBackingStoreBuffered defer:NO];
[window setTitle:@"My Window"];
[window center];
WindowDelegate *delegate = [[WindowDelegate alloc] init];
[window setDelegate:delegate];
[window makeKeyWindow];
[window orderFrontRegardless];
[NSApp run];
}
}
@end
@implementation WindowDelegate
- (BOOL)windowShouldClose:(id)sender
{
[NSApp terminate:nil];
return YES;
}
@end
2. 创建一个文件(仍然是Objective-C),使用关键字 extern "C" 来包含C++头文件(以便在C++代码中使用):
WindowBuilderObjCWrapper.mm
extern "C"
{
#import "WindowBuilderObjC.h"
}
extern "C" WindowBuilderObjC *createWindowBuilder()
{
WindowBuilderObjC* builder = [[WindowBuilderObjC alloc] init];
return builder;
}
extern "C" void deleteWindowBuilder(WindowBuilderObjC *builder)
{
[builder dealloc];
}
extern "C" void buildWindow(WindowBuilderObjC *builder, int* width, int* height)
{
[builder buildWindowWithWidth:*width height:*height];
}
3. 修改CMakeLists.txt以从Objective-C文件创建一个模块库:
CMakeLists.txt
add_library(WindowBuilderObjCLib MODULE
src/Utils/WindowBuilder/macOS/Objective-C/WindowBuilderObjCWrapper.mm
)
target_sources(WindowBuilderObjCLib
PRIVATE
src/Utils/WindowBuilder/macOS/Objective-C/WindowBuilderObjC.h
src/Utils/WindowBuilder/macOS/Objective-C/WindowBuilderObjC.mm
)
target_link_libraries(WindowBuilderObjCLib
PRIVATE "-framework Cocoa"
PRIVATE "-framework Foundation"
PRIVATE "-framework AppKit"
)
# 设置库的语言为Objective-C++
set_target_properties(WindowBuilderObjCLib PROPERTIES
LINKER_LANGUAGE "CXX"
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES YES
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_WEAK YES
)
4. 在C++中按照以下步骤操作:
4.1. 使用 dlfcn.h 库打开库:
// 打开库
lib_handle = dlopen("./build/libWindowBuilderObjCLib.so", RTLD_LOCAL);
if (!lib_handle)
{
exit(EXIT_FAILURE);
}
4.2.(可选)使用 boost 库来检查打开的库是否包含所需的函数签名:
// 引入Boost库用于库信息
#include <boost/dll/library_info.hpp>
static void PrintSymbols(std::string libPath)
{
// 类`library_info`可以从库中提取信息
boost::dll::library_info inf(libPath);
// 获取导出符号
std::vector<std::string> exports = inf.symbols();
// 打印符号
for (std::size_t j = 0; j < exports.size(); ++j)
{
std::cout << exports[j] << std::endl;
}
}
4.3.(可选)在C++类中创建将使用库函数的方法签名(也可以根据签名构建自己的实现):
// Objective-C包装器的签名
typedef void (*buildWindowObjC)(void *builder, int *width, int *height);
typedef void *(*createWindowBuilderObjC)();
typedef void *(*deleteWindowBuilderObjC)(void *builder);
// Objective-C处理程序
createWindowBuilderObjC createWindowBuilderObjCHandler;
buildWindowObjC buildWindowObjCHandler;
deleteWindowBuilderObjC deleteWindowBuilderObjCHandler;
// Objective-C窗口构建器实例
void *windowBuilderObjC;
4.4. 从库中获取函数并将其转换为适当的签名:
// 加载函数
createWindowBuilderObjCHandler = reinterpret_cast<createWindowBuilderObjC>(dlsym(lib_handle, "createWindowBuilder"));
if (!createWindowBuilderObjCHandler)
{
exit(EXIT_FAILURE);
}
buildWindowObjCHandler = reinterpret_cast<buildWindowObjC>(dlsym(lib_handle, "buildWindow"));
if (!buildWindowObjCHandler)
{
exit(EXIT_FAILURE);
}
deleteWindowBuilderObjCHandler = reinterpret_cast<deleteWindowBuilderObjC>(dlsym(lib_handle, "deleteWindowBuilder"));
if (!deleteWindowBuilderObjCHandler)
{
exit(EXIT_FAILURE);
}
4.5. 使用Objective-C函数(通过C++头文件)从导入的库中调用:
windowBuilderObjC = createWindowBuilderObjCHandler();
int width = size.GetWidth();
int height = size.GetHeight();
buildWindowObjCHandler(windowBuilderObjC, &width, &height);
// ...
deleteWindowBuilderObjCHandler(windowBuilderObjC);
// ...
以上是你提供的代码的翻译。
英文:
So for anyone who's looking for such kind of implementation to be used:
1. Write code in Objective-C that provides a functionality you want (in my case, creating a window in macOS):
WindowBuilderObjC.h
#ifndef WindowBuilderObjC_h
#define WindowBuilderObjC_h
#import <Cocoa/Cocoa.h>
@interface WindowBuilderObjC : NSObject
- (void)buildWindowWithWidth:(int)width height:(int)height;
@end
@interface WindowDelegate : NSObject <NSWindowDelegate>
@end
#endif /* WindowBuilderObjC_h */
WindowBuilderObjC.mm
#import "WindowBuilderObjC.h"
@implementation WindowBuilderObjC
- (void)buildWindowWithWidth:(int)width height:(int)height
{
@autoreleasepool
{
[NSApplication sharedApplication];
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
NSRect frame = NSMakeRect(0, 0, 800, 600);
NSUInteger style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable;
NSWindow *window = [[NSWindow alloc] initWithContentRect:frame styleMask:style backing:NSBackingStoreBuffered defer:NO];
[window setTitle:@"My Window"];
[window center];
WindowDelegate *delegate = [[WindowDelegate alloc] init];
[window setDelegate:delegate];
[window makeKeyWindow];
[window orderFrontRegardless];
[NSApp run];
}
}
@end
@implementation WindowDelegate
- (BOOL)windowShouldClose:(id)sender
{
[NSApp terminate:nil];
return YES;
}
@end
2. Create a file (still in Objective-C) with C++ headers using keyword extern "C" (so they can be used in C++ code):
WindowBuilderObjCWrapper.mm
extern "C"
{
#import "WindowBuilderObjC.h"
}
extern "C" WindowBuilderObjC *createWindowBuilder()
{
WindowBuilderObjC* builder = [[WindowBuilderObjC alloc] init];
return builder;
}
extern "C" void deleteWindowBuilder(WindowBuilderObjC *builder)
{
[builder dealloc];
}
extern "C" void buildWindow(WindowBuilderObjC *builder, int* width, int* height)
{
[builder buildWindowWithWidth:*width height:*height];
}
3. Modify CMakeLists.txt to create a module library from your Objective-C files:
CMakeLists.txt
add_library(WindowBuilderObjCLib MODULE
src/Utils/WindowBuilder/macOS/Objective-C/WindowBuilderObjCWrapper.mm
)
target_sources(WindowBuilderObjCLib
PRIVATE
src/Utils/WindowBuilder/macOS/Objective-C/WindowBuilderObjC.h
src/Utils/WindowBuilder/macOS/Objective-C/WindowBuilderObjC.mm
)
target_link_libraries(WindowBuilderObjCLib
PRIVATE "-framework Cocoa"
PRIVATE "-framework Foundation"
PRIVATE "-framework AppKit"
)
# Set the language for the library to Objective-C++
set_target_properties(WindowBuilderObjCLib PROPERTIES
LINKER_LANGUAGE "CXX"
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES YES
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_WEAK YES
)
4. In C++ follow these steps:
4.1. Open the library using dlfcn.h lib:
// Open the library.
lib_handle = dlopen("./build/libWindowBuilderObjCLib.so", RTLD_LOCAL);
if (!lib_handle)
{
exit(EXIT_FAILURE);
}
4.2. (Optional) Use boost lib to check if the opened library contains the required function signatures:
// Boost for lib info
#include <boost/dll/library_info.hpp>
static void PrintSymbols(std::string libPath)
{
// Class `library_info` can extract information from a library
boost::dll::library_info inf(libPath);
// Getting exported symbols
std::vector<std::string> exports = inf.symbols();
// Printing symbols
for (std::size_t j = 0; j < exports.size(); ++j)
{
std::cout << exports[j] << std::endl;
}
}
4.3. (Optional) Create method signatures in the C++ class that is going to use the library's functions (you can also build up your own implementation based on the signatures):
// Objective-C wrapper signatures
typedef void (*buildWindowObjC)(void *builder, int *width, int *height);
typedef void *(*createWindowBuilderObjC)();
typedef void *(*deleteWindowBuilderObjC)(void *builder);
// Objective-C handlers
createWindowBuilderObjC createWindowBuilderObjCHandler;
buildWindowObjC buildWindowObjCHandler;
deleteWindowBuilderObjC deleteWindowBuilderObjCHandler;
// Objective-C Window Builder Instance
void *windowBuilderObjC;
4.4. Get functions from the library and cast it to the suitable signature:
// Load functions
createWindowBuilderObjCHandler = reinterpret_cast<createWindowBuilderObjC>(dlsym(lib_handle, "createWindowBuilder"));
if (!createWindowBuilderObjCHandler)
{
exit(EXIT_FAILURE);
}
buildWindowObjCHandler = reinterpret_cast<buildWindowObjC>(dlsym(lib_handle, "buildWindow"));
if (!buildWindowObjCHandler)
{
exit(EXIT_FAILURE);
}
deleteWindowBuilderObjCHandler = reinterpret_cast<deleteWindowBuilderObjC>(dlsym(lib_handle, "deleteWindowBuilder"));
if (!deleteWindowBuilderObjCHandler)
{
exit(EXIT_FAILURE);
}
4.5. Use the Objective-C functions (via C++ headers) from the imported library:
windowBuilderObjC = createWindowBuilderObjCHandler();
int width = size.GetWidth();
int height = size.GetHeight();
buildWindowObjCHandler(windowBuilderObjC, &width, &height);
// ...
deleteWindowBuilderObjCHandler(windowBuilderObjC);
// ...
Thats it. Hope it can be useful for someone.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论