调用 ObjC++ 时未定义的符号来自 C++ 的方法
我在这里关注这个答案< /a> 使用 C++ 为 React Native 构建 TurboModule
但是,我需要使用仅在 AVFoundation 框架中可用的 Apple 库,该框架仅适用于 Obj-C 和 C++
因此,我认为我可以从常规 C++ 或至少很多互联网答案中调用 Obj-C++ 方法所见告诉我,我可以。
尽管如此,当我尝试编译 TurboModule 时,出现以下错误:
stderr: Undefined symbols for architecture x86_64:
"MyClassImpl::doSomethingWith(void*)", referenced from:
MyCPPClass::doSomethingWithMyClass() in libOneRecognizerTurboModuleApple--830559412.a(MyCPPClass.cpp.o)
"MyClassImpl::logMyMessage(char*)", referenced from:
MyCPPClass::doSomethingWithMyClass() in libOneRecognizerTurboModuleApple--830559412.a(MyCPPClass.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我将其与以下文件放在一起的方式:
MyObject-C-Interface.h
#ifndef __MYOBJECT_C_INTERFACE_H__
#define __MYOBJECT_C_INTERFACE_H__
class MyClassImpl {
public:
MyClassImpl(void);
~MyClassImpl(void);
void init(void);
int doSomethingWith(void* aParameter);
void logMyMessage(char* aCStr);
private:
void* self;
};
#endif
MyObject.h
#import "MyObject-C-Interface.h"
@interface MyObject : NSObject {
int someVar;
}
- (int)doSomethingWith:(void*)aParameter;
- (void)logMyMessage:(char*)aCStr;
@end
MyObject.mm
#import "MyObject.h"
@implementation MyObject
MyClassImpl::MyClassImpl(void) : self(NULL) {}
MyClassImpl::~MyClassImpl(void) {
[(id)self dealloc];
}
void MyClassImpl::init(void) {
self = [[MyObject alloc] init];
}
int MyClassImpl::doSomethingWith(void* aParameter) {
return [(id)self doSomethingWith:aParameter];
}
void MyClassImpl::logMyMessage(char* aCStr) {
[(id)self doLogMessage:aCStr];
}
- (int)doSomethingWith:(void*)aParameter {
int result;
return result;
}
- (void)logMyMessage:(char*)aCStr {
NSLog(aCStr);
}
@end
MyCppClass.h
#ifndef __MYCPP_CLASS_H__
#define __MYCPP_CLASS_H__
class MyClassImpl;
class MyCPPClass {
enum { cANSWER_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING = 42 };
public:
MyCPPClass(void);
~MyCPPClass(void);
void init(void);
int doSomethingWithMyClass(void);
private:
MyClassImpl* _impl;
int _myValue;
};
#endif
MyCppClass.cpp
#include "MyCPPClass.h"
#include "MyObject-C-Interface.h"
MyCPPClass::MyCPPClass(void) : _impl(NULL) {}
void MyCPPClass::init(void) {
_impl = new MyClassImpl();
}
MyCPPClass::~MyCPPClass(void) {
if (_impl) {
delete _impl;
_impl = NULL;
}
}
int MyCPPClass::doSomethingWithMyClass(void) {
int result = _impl->doSomethingWith(&_myValue);
if (result == cANSWER_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING) {
_impl->logMyMessage((char*)"Hello, Arthur!");
} else {
_impl->logMyMessage((char*)"Don't worry.");
}
return result;
}
并从我的 TurboModule 中以这种方式调用它:
MyTurboModule.cpp
#include "MyCPPClass.h"
// rest of libraries
jsi::Value OneRecognizerTurboModule::getValueWithPromise(
jsi::Runtime& rt,
bool error) {
return createPromiseAsJSIValue(
rt, [error](jsi::Runtime& rt2, std::shared_ptr<Promise> promise) {
if (error) {
promise->reject("intentional promise rejection");
} else {
MyCPPClass* css;
css = new MyCPPClass();
css->doSomethingWithMyClass();
promise->resolve(jsi::String::createFromUtf8(rt2, "hello from c++!"));
}
});
}
我认为这应该可行,但链接器抱怨符号对于我的体系结构未定义。我在互联网上浏览到这个错误是不明确的,与我的体系结构无关,更多地与我调用函数的方式有关,但我对 C++ 完全陌生,所以我不确定我是什么我做错了。
我在实现中调用 ObjC++ 方法的方式有什么问题?
I'm following this answer here to build a TurboModule for React Native using C++
However, I need to use an Apple library that is only available in the AVFoundation framework which only works for Obj-C and C++
Therefore, I thought I could call Obj-C++ methods from regular C++ or at least a lot of the internet answers I've seen tells me that I can.
Nonetheless, when I try to compile my TurboModule, I get the following error:
stderr: Undefined symbols for architecture x86_64:
"MyClassImpl::doSomethingWith(void*)", referenced from:
MyCPPClass::doSomethingWithMyClass() in libOneRecognizerTurboModuleApple--830559412.a(MyCPPClass.cpp.o)
"MyClassImpl::logMyMessage(char*)", referenced from:
MyCPPClass::doSomethingWithMyClass() in libOneRecognizerTurboModuleApple--830559412.a(MyCPPClass.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The way that I'm putting this together is with the following files:
MyObject-C-Interface.h
#ifndef __MYOBJECT_C_INTERFACE_H__
#define __MYOBJECT_C_INTERFACE_H__
class MyClassImpl {
public:
MyClassImpl(void);
~MyClassImpl(void);
void init(void);
int doSomethingWith(void* aParameter);
void logMyMessage(char* aCStr);
private:
void* self;
};
#endif
MyObject.h
#import "MyObject-C-Interface.h"
@interface MyObject : NSObject {
int someVar;
}
- (int)doSomethingWith:(void*)aParameter;
- (void)logMyMessage:(char*)aCStr;
@end
MyObject.mm
#import "MyObject.h"
@implementation MyObject
MyClassImpl::MyClassImpl(void) : self(NULL) {}
MyClassImpl::~MyClassImpl(void) {
[(id)self dealloc];
}
void MyClassImpl::init(void) {
self = [[MyObject alloc] init];
}
int MyClassImpl::doSomethingWith(void* aParameter) {
return [(id)self doSomethingWith:aParameter];
}
void MyClassImpl::logMyMessage(char* aCStr) {
[(id)self doLogMessage:aCStr];
}
- (int)doSomethingWith:(void*)aParameter {
int result;
return result;
}
- (void)logMyMessage:(char*)aCStr {
NSLog(aCStr);
}
@end
MyCppClass.h
#ifndef __MYCPP_CLASS_H__
#define __MYCPP_CLASS_H__
class MyClassImpl;
class MyCPPClass {
enum { cANSWER_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING = 42 };
public:
MyCPPClass(void);
~MyCPPClass(void);
void init(void);
int doSomethingWithMyClass(void);
private:
MyClassImpl* _impl;
int _myValue;
};
#endif
MyCppClass.cpp
#include "MyCPPClass.h"
#include "MyObject-C-Interface.h"
MyCPPClass::MyCPPClass(void) : _impl(NULL) {}
void MyCPPClass::init(void) {
_impl = new MyClassImpl();
}
MyCPPClass::~MyCPPClass(void) {
if (_impl) {
delete _impl;
_impl = NULL;
}
}
int MyCPPClass::doSomethingWithMyClass(void) {
int result = _impl->doSomethingWith(&_myValue);
if (result == cANSWER_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING) {
_impl->logMyMessage((char*)"Hello, Arthur!");
} else {
_impl->logMyMessage((char*)"Don't worry.");
}
return result;
}
And calling it this way from my TurboModule:
MyTurboModule.cpp
#include "MyCPPClass.h"
// rest of libraries
jsi::Value OneRecognizerTurboModule::getValueWithPromise(
jsi::Runtime& rt,
bool error) {
return createPromiseAsJSIValue(
rt, [error](jsi::Runtime& rt2, std::shared_ptr<Promise> promise) {
if (error) {
promise->reject("intentional promise rejection");
} else {
MyCPPClass* css;
css = new MyCPPClass();
css->doSomethingWithMyClass();
promise->resolve(jsi::String::createFromUtf8(rt2, "hello from c++!"));
}
});
}
I think that should work, but the linker is complaining that the symbols are undefined for my architecture. I browsed on the internet that this error is ambiguous and has nothing to do with my architecture and more to do with the way that I'm calling the function, but I'm completely new to C++ so I'm not sure what I'm doing wrong.
What's wrong with the way I'm calling the ObjC++ method in my implementation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在我看来,您的
MyObject.mm
文件要么没有被编译,要么它的目标代码没有链接到您的最终二进制文件中。-ObjC++
),并且生成的目标代码文件 (MyObject.o
) 包含在链接步骤中。It sounds to me as if your
MyObject.mm
file is either not being compiled, or its object code is not being linked into your final binary.-ObjC++
) and that the resulting object code file (MyObject.o
) is included in the link step.