我试图在Swift 4项目中使用Freeglut库。
{"salonphoebe":true,"salonvo":false}
函数移至Swift,其声明为
void glutInit(int *argcp, char **argv);
由于我不需要命令行中的实际参数,因此我想组成两个参数。我试图在Bridging-Header.h文件中定义func glutInit(_ pargc: UnsafeMutablePointer<Int32>!, _ argv: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>!)
**argv
并在main.swift中使用它们
#include <OpenGL/gl.h>
#include <GL/glut.h>
char ** argv[1] = {"t"};
但是有了glutInit(),我得到了func main() {
var argcp: Int32 = 1
glutInit(&argcp, argv!) // EXC_BAD_ACCESS
glutInitDisplayMode(UInt32(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH));
glutCreateWindow("my project")
glutDisplayFunc(display)
initOpenGL()
glutMainLoop()
。
如何正确初始化过剩?如何获得Thread 1: EXC_BAD_ACCESS (code=1, address=0x74)
才能正常工作?
答案 0 :(得分:0)
C char * argv[1] = {"t"};
中正确的代码不起作用的原因是因为Swift将固定大小的C数组作为元组而不是第一个元素的指针导入。
但是您的char ** argv[1] = {"t"};
是完全错误的。 argv
的每个元素都必须为char **
,但是您要分配char *
("t"
)。 Xcode在首次构建时必须向您显示警告:
warning: incompatible pointer types initializing 'char **' with an expression of type 'char [2]'
除非您完全知道自己在做什么,否则最好将incompatible pointer types
警告视为错误。
通常,您最好不要在头文件中编写一些生成实际代码/数据的代码,例如char * argv[1] = {"t"};
。
您可以尝试使用Swift代码。
您知道,要传递指向单个元素T
的指针时,需要声明类型var
的{{1}}并将T
传递给调用的函数
与代码中的&varName
一样。
同样,当您要传递指向多个元素argcp
的指针时,您声明类型为 T
var >( [T]
),并将Array<T>
传递给您调用的函数。
(忽略不可变的情况以简化操作。)
参数&arrName
符合这种情况,其中argv
。
因此声明类型为T == UnsafeMutablePointer<Int8>?
的{{1}}。
var
但是我想知道您是否真的想将某些东西传递给[UnsafeMutablePointer<Int8>?]
。
您可以尝试以下操作:
func main() {
var argc: Int32 = 1
var argv: [UnsafeMutablePointer<Int8>?] = [
strdup("t")
]
defer { argv.forEach{free($0)} }
glutInit(&argc, &argv)
//...
}
我不确定freeglut是否接受此方法,但是您可以在网上找到一些文章说它们可以在Glut的某些实现中起作用。