Golang中如何使用Import "C"导入非标准C++库

Golang中如何使用Import "C"导入非标准C++库 我正在尝试在VS Code(不是Visual Studio)中使用import "C"调用C++代码。对于仅需标准库的简单"hello world"程序,这可以正常工作。然而,当我尝试调用需要其自身库的OpenCV代码时,编译器无法找到这些库:

# command-line-arguments
.\cam.go:4:10: fatal error: opencv2/opencv.hpp: No such file or directory
    4 | //#include <opencv2/opencv.hpp>
      |          ^~~~~~~~~~~~~~~~~~~~
compilation terminated.

以下是我的代码。这是一个用于从指定目录打开jpg图像的程序。

package main

//#include <stdio.h>
//#include <opencv2/opencv.hpp>
//
//using namespace cv;
//int main(int argc, char** argv )
//{
//
//Mat image;
//image = imread("C:\\Users\\Desktop\\profile-picture.jpg");
//if ( !image.data )
//{
//printf("No image data \n");
//return -1;
//}
//namedWindow("Display Image", WINDOW_AUTOSIZE );
//imshow("Display Image", image);
//waitKey(0);
//return 0;
//}
import "C"

func main() {

}

我该如何向编译器指明库文件的位置?我认为问题就在这里。


更多关于Golang中如何使用Import "C"导入非标准C++库的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

这更多是关于C语言而非Go语言。cgo允许Go调用C代码。-I、-L和-l是C编译器和链接器的标志。你需要真正理解它们的工作原理才能正确指定参数,但简而言之,-I指向包含需要被#include的文件的目录。-L指向包含库文件的目录,而-l指定需要链接的库。

将你的C代码提取到一个.c文件中,并尝试用C编译器编译它,这样做可能会很有帮助。这样你就会知道需要为cgo指定什么参数。

更多关于Golang中如何使用Import "C"导入非标准C++库的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你需要告诉cgo去哪里查找。以下是从我的代码中提取的一个片段,供你参考:

/*
#cgo windows CFLAGS: -DTAG_WINDOWS
#cgo linux freebsd CFLAGS: -DTAG_POSIX
#cgo linux freebsd LDFLAGS: -ldl
#cgo CFLAGS: -I ${SRCDIR}/sdk/samples/common/inc
*/

favicon.ico

cgo command - cmd/cgo - Go Packages

Cgo使得创建能够调用C代码的Go包成为可能。

可以在这些注释中使用伪指令 #cgo 来定义 CFLAGS、CPPFLAGS、CXXFLAGS、FFLAGS 和 LDFLAGS,以调整 C、C++ 或 Fortran 编译器的行为。

很遗憾,我没有理解这份文档。这看起来不像Go语言一贯的友好风格。首先,我不知道应该引用哪个目录。下面我写了一个简短的OpenCV文件夹结构:

C:Opencv/
├─ build/
│  ├─ bin/
│  ├─ etc/
│  ├─ x64/
│      ├─ vc14/
│      ├─ vc15/
│          ├─ bin/
│          ├─ lib/
│  ├─ python/
│  ├─ java/
│  ├─ include/
│          ├─ opencv2/
│              ├─ opencv.hpp
├─ sources/
│  ├─ 3rdparty/
│  ├─ apps/
│  ├─ cmake/
│  ├─ data/
│  ├─ doc/
│  ├─ include/
│      ├─ opencv2/
│          ├─ opencv.hpp
│  ├─ modules/
│  ├─ platforms/
│  ├─ samples/

在标志 // #cgo LDFLAGS: -L${SRCDIR}/libs -lfoo 中,我应该使用哪个目录来调用 #include <opencv2/opencv.hpp>,是源代码目录还是构建目录?如何将其写在 -L${SRCDIR} 里面?从上面的结构可以看出,库目录和包含文件的目录并不相同。请帮帮我,这甚至看起来不像我热爱的Go了。

在Go中使用import "C"调用C++库时,需要正确配置CGO的编译和链接参数。对于OpenCV这样的非标准库,需要在Go文件中通过注释指定头文件路径和链接库。

以下是修改后的代码示例:

package main

/*
#cgo CXXFLAGS: -std=c++11
#cgo LDFLAGS: -L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_imgproc

#include <opencv2/opencv.hpp>
#include <stdio.h>

using namespace cv;

void displayImage(const char* path) {
    Mat image = imread(path);
    if (image.empty()) {
        printf("No image data \n");
        return;
    }
    namedWindow("Display Image", WINDOW_AUTOSIZE);
    imshow("Display Image", image);
    waitKey(0);
    destroyWindow("Display Image");
}
*/
import "C"
import "unsafe"

func main() {
    imagePath := "C:\\Users\\Desktop\\profile-picture.jpg"
    cPath := C.CString(imagePath)
    defer C.free(unsafe.Pointer(cPath))
    
    C.displayImage(cPath)
}

关键配置说明:

  1. 头文件路径:如果OpenCV头文件不在标准路径,需要添加-I参数:
// #cgo CFLAGS: -I/usr/local/include/opencv4
// #cgo CXXFLAGS: -I/usr/local/include/opencv4 -std=c++11
  1. 库文件路径:根据OpenCV安装位置调整-L参数:
// #cgo LDFLAGS: -L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_highgui
  1. Windows系统需要指定MinGW路径:
// #cgo windows CFLAGS: -IC:/opencv/build/include
// #cgo windows LDFLAGS: -LC:/opencv/build/x64/mingw/lib -lopencv_core455 -lopencv_highgui455 -lopencv_imgcodecs455
  1. 编译命令:确保使用C++编译器:
CGO_ENABLED=1 GOOS=windows go build -o app.exe

注意:OpenCV的C++代码需要在import "C"上方的注释块中声明,且不能包含main函数。所有C++函数需要通过C接口暴露给Go调用。

回到顶部