C++ 和 Swift:无法使用参数列表“(Int)”调用 'externalMethodName'
C++ and Swift: Cannot invoke 'externalMethodName' with an argument list of '(Int)'
我正在努力构建一个 swift 应用程序,它使用自己编写的 C++ class。
我让它与所需的 Objective-C++ 包装器一起工作,但现在我遇到了问题,我无法使用 int 参数调用外部方法。模糊地它适用于纯数字。
示例如下:
片段来自 Swift class:
let validNumber = 5
let refScen = CppToObjCWrapper()
let result = refScen.getCalcLoad(validNumber!)
CppToObjCWrapper.mm中对应的wrapper方法:
-(float)getCalcLoad:(int)value {
RefScenLibCpp refScen;
NSLog(@"Inside Wrapper. Value received: %d", value);
return refScen.getCalcLoad(value);
}
以及RefScenLibCpp.cpp中的C++方法:
float RefScenLibCpp::getCalcLoad(int value) {
return result / 255 * 100;
}
如我所说,如果我尝试从 swift class 调用此方法,它会抛出错误:
Cannot invoke 'getCalcLoad' with an argument list of '(Int)'
但是,如果我从 Swift class 调用方法时只使用一个数字,例如:
let result = refScen.getCalcLoad(42)
效果很好!我现在花了很多时间来寻找这个问题,但是当我使用 Objective-C++ 和 C++ 时,我认为我还没有找到正确的答案。使用(非)选项的不同方法没有帮助。更让我感到困惑的是,我有一个类似的 C++ 方法,它接受一个 String 参数,我调用它就像使用 int 参数的方法一样,但这个方法工作得很好。我希望有人能帮助我。
为了演示这个问题,我在 Swift 操场上用一个最小的例子重现了这个错误:
func aFuncTakingInt32(val: Int32) {
// do stuff
}
let validNumber = 42
aFuncTakingInt32(validNumber)
此代码生成相同的错误:
Cannot invoke 'aFuncTakingInt32' with an argument list of type '(Int)'
如果我们将 validNumber
的类型明确更改为 Int32
:
let validNumber: Int32 = 42
或者如果我们在调用函数时从 Int
构造一个 Int32
:
aFuncTakingInt32(Int32(validNumber))
错误消失,代码 运行 完全没问题。
作为解决此问题的额外有用细节,因为我们尝试使用的方法未在 Swift 中定义,而是在我们导入的 Objective-C++ 文件中定义, 有 IS 一种方法可以准确地找出函数在 Swift 结束时期望的参数类型。如果您键入方法名称,并按住 Alt 键并单击方法名称,您将获得一些有用的信息:
现在我们可以看到 Swift 期望传递给该方法的 显式 类型。在这里,它清楚地标记为 Int32
变量(我们已经知道,因为我们刚刚在 Swift 中编写了该方法)。当我们无法访问源代码或不确定 Swift 如何将代码从一种语言翻译成 Swift.
时,这会非常有用
Swift 的 Int
类型不同于 Objective-C、C、C++ 和许多其他语言的 int
原语。 Swift 的 Int
更类似于 Objective-C 的 NSInteger
.
如果我们尝试将 Objective-C 的 NSInteger
传递给此 C++ 方法,它会编译,但可能会生成警告(相对于 Swift 的错误)。那是因为 Objective-C 远没有那么严格并且愿意对基元进行一些隐式转换。
话虽如此,Swift 有一些类型更等同于 C、C++ 和 Objective-C 的 int
(以及其他大小的整数)。在这里,我们很可能想要 Int32
.
我们可以使用 let result = refScen.getCalcLoad(42)
的原因是因为虽然 42
是一个默认情况下将被解释为 Int
的文字(正如我们在 let validNumber = 42
中看到的), 它也可以解释为许多其他数字类型,包括 Int32
(甚至浮点类型)。
但是,当我们执行以下操作时:
let validNumber = 42
此处,validNumber
必须隐式推断显式类型。它推断的类型是 Int
(不同于 Objective-C、C 和 C++ 的 int
)。
所以当我们尝试以下操作时:
let validNumber = 42
let result = refScen.getCalcLoad(validNumber)
我们正在尝试将 Int
传递给需要 Int32
的方法,并且因为 Swift 对参数类型非常非常严格,它允许我们通过,它会生成错误(其中 Objective-C 可能会生成警告)。
我们应该能够通过明确声明 validNumber
的类型来解决这个问题,Int32
:
let validNumber: Int32 = 42
let result = refScen.getCalcLoad(validNumber)
但另外,如果在 Swift 端将此变量的类型保持为 Int32
没有意义,我们 可以 构造一个Int32
出 Int
,所以我们可以这样做:
let validNumber = 42
let result = refScen.getCalcLoad(Int32(validNumber))
作为额外的警告,我们不会 运行 使用 String
解决这个问题,因为 Objective-C 的 NSString
映射到 Swift' s String
。我们也不会 运行 解决这个问题 char
映射到 Swift 的 Character
或 bool
映射到 Swift 的Bool
.
我正在努力构建一个 swift 应用程序,它使用自己编写的 C++ class。
我让它与所需的 Objective-C++ 包装器一起工作,但现在我遇到了问题,我无法使用 int 参数调用外部方法。模糊地它适用于纯数字。
示例如下:
片段来自 Swift class:
let validNumber = 5
let refScen = CppToObjCWrapper()
let result = refScen.getCalcLoad(validNumber!)
CppToObjCWrapper.mm中对应的wrapper方法:
-(float)getCalcLoad:(int)value {
RefScenLibCpp refScen;
NSLog(@"Inside Wrapper. Value received: %d", value);
return refScen.getCalcLoad(value);
}
以及RefScenLibCpp.cpp中的C++方法:
float RefScenLibCpp::getCalcLoad(int value) {
return result / 255 * 100;
}
如我所说,如果我尝试从 swift class 调用此方法,它会抛出错误:
Cannot invoke 'getCalcLoad' with an argument list of '(Int)'
但是,如果我从 Swift class 调用方法时只使用一个数字,例如:
let result = refScen.getCalcLoad(42)
效果很好!我现在花了很多时间来寻找这个问题,但是当我使用 Objective-C++ 和 C++ 时,我认为我还没有找到正确的答案。使用(非)选项的不同方法没有帮助。更让我感到困惑的是,我有一个类似的 C++ 方法,它接受一个 String 参数,我调用它就像使用 int 参数的方法一样,但这个方法工作得很好。我希望有人能帮助我。
为了演示这个问题,我在 Swift 操场上用一个最小的例子重现了这个错误:
func aFuncTakingInt32(val: Int32) {
// do stuff
}
let validNumber = 42
aFuncTakingInt32(validNumber)
此代码生成相同的错误:
Cannot invoke 'aFuncTakingInt32' with an argument list of type '(Int)'
如果我们将 validNumber
的类型明确更改为 Int32
:
let validNumber: Int32 = 42
或者如果我们在调用函数时从 Int
构造一个 Int32
:
aFuncTakingInt32(Int32(validNumber))
错误消失,代码 运行 完全没问题。
作为解决此问题的额外有用细节,因为我们尝试使用的方法未在 Swift 中定义,而是在我们导入的 Objective-C++ 文件中定义, 有 IS 一种方法可以准确地找出函数在 Swift 结束时期望的参数类型。如果您键入方法名称,并按住 Alt 键并单击方法名称,您将获得一些有用的信息:
现在我们可以看到 Swift 期望传递给该方法的 显式 类型。在这里,它清楚地标记为 Int32
变量(我们已经知道,因为我们刚刚在 Swift 中编写了该方法)。当我们无法访问源代码或不确定 Swift 如何将代码从一种语言翻译成 Swift.
Swift 的 Int
类型不同于 Objective-C、C、C++ 和许多其他语言的 int
原语。 Swift 的 Int
更类似于 Objective-C 的 NSInteger
.
如果我们尝试将 Objective-C 的 NSInteger
传递给此 C++ 方法,它会编译,但可能会生成警告(相对于 Swift 的错误)。那是因为 Objective-C 远没有那么严格并且愿意对基元进行一些隐式转换。
话虽如此,Swift 有一些类型更等同于 C、C++ 和 Objective-C 的 int
(以及其他大小的整数)。在这里,我们很可能想要 Int32
.
我们可以使用 let result = refScen.getCalcLoad(42)
的原因是因为虽然 42
是一个默认情况下将被解释为 Int
的文字(正如我们在 let validNumber = 42
中看到的), 它也可以解释为许多其他数字类型,包括 Int32
(甚至浮点类型)。
但是,当我们执行以下操作时:
let validNumber = 42
此处,validNumber
必须隐式推断显式类型。它推断的类型是 Int
(不同于 Objective-C、C 和 C++ 的 int
)。
所以当我们尝试以下操作时:
let validNumber = 42 let result = refScen.getCalcLoad(validNumber)
我们正在尝试将 Int
传递给需要 Int32
的方法,并且因为 Swift 对参数类型非常非常严格,它允许我们通过,它会生成错误(其中 Objective-C 可能会生成警告)。
我们应该能够通过明确声明 validNumber
的类型来解决这个问题,Int32
:
let validNumber: Int32 = 42
let result = refScen.getCalcLoad(validNumber)
但另外,如果在 Swift 端将此变量的类型保持为 Int32
没有意义,我们 可以 构造一个Int32
出 Int
,所以我们可以这样做:
let validNumber = 42
let result = refScen.getCalcLoad(Int32(validNumber))
作为额外的警告,我们不会 运行 使用 String
解决这个问题,因为 Objective-C 的 NSString
映射到 Swift' s String
。我们也不会 运行 解决这个问题 char
映射到 Swift 的 Character
或 bool
映射到 Swift 的Bool
.