2015-07-17 19 views
7

Tôi đang cố gắng liên kết các chương trình C++ OpenCV với Go. Tôi đang sử dụng khái niệm từ How do you statically link a c library in go using cgo? [1]. tập tin myimgcom.cpp của tôi là:Liên kết C++ với Go

/** 
* @file SURF_FlannMatcher 
* @brief SURF detector + descriptor + FLANN Matcher 
* @author A. Huaman 
Edited: nnnnn 
*/ 

#include <stdio.h> 
#include <string> 
#include <iostream> 
#include "opencv2/core/core.hpp" 
#include "opencv2/features2d/features2d.hpp" 
#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/nonfree/features2d.hpp" 

using namespace cv; 

void readme(); 

int mysurf(int myarg) 
{ 

string option1= "./Lenna.png"; 
string option2= "./Lenna.png"; 

if(myarg != 3) 
{ readme(); return -1; } 

std::cout << option1 << option2; 

Mat img_1 = imread(option1, CV_LOAD_IMAGE_GRAYSCALE); 
Mat img_2 = imread(option2, CV_LOAD_IMAGE_GRAYSCALE); 

if(!img_1.data || !img_2.data) 
{ std::cout<< " --(!) Error reading images " << std::endl; return -1; } 

//-- Step 1: Detect the keypoints using SURF Detector 
int minHessian = 400; 

SurfFeatureDetector detector(minHessian); 

std::vector<KeyPoint> keypoints_1, keypoints_2; 

detector.detect(img_1, keypoints_1); 
detector.detect(img_2, keypoints_2); 

//-- Step 2: Calculate descriptors (feature vectors) 
SurfDescriptorExtractor extractor; 

Mat descriptors_1, descriptors_2; 

extractor.compute(img_1, keypoints_1, descriptors_1); 
extractor.compute(img_2, keypoints_2, descriptors_2); 

//-- Step 3: Matching descriptor vectors using FLANN matcher 
FlannBasedMatcher matcher; 
std::vector<DMatch> matches; 
matcher.match(descriptors_1, descriptors_2, matches); 

double max_dist = 0; double min_dist = 100; 

//-- Quick calculation of max and min distances between keypoints 
for(int i = 0; i < descriptors_1.rows; i++) 
{ double dist = matches[i].distance; 
    if(dist < min_dist) min_dist = dist; 
    if(dist > max_dist) max_dist = dist; 
} 

    printf("-- Max dist : %f \n", max_dist); 
    printf("-- Min dist : %f \n", min_dist); 

    std::vector<DMatch> good_matches; 

    for(int i = 0; i < descriptors_1.rows; i++) 
    { if(matches[i].distance <= max(4*min_dist, 0.02)) 
    { good_matches.push_back(matches[i]); } 
    } 

    //-- Draw only "good" matches 
    Mat img_matches; 
    drawMatches(img_1, keypoints_1, img_2, keypoints_2, 
      good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), 
      vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); 

    //-- Show detected matches 
    imshow("Good Matches", img_matches); 

    for(int i = 0; i < (int)good_matches.size(); i++) 
    { printf("-- Good Match [%d] Keypoint 1: %d -- Keypoint 2: %d \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx); } 

    waitKey(0); 

    return 0; 
} 


void readme() 
{ std::cout << " Usage: ./SURF_FlannMatcher <img1> <img2>" << std::endl; } 

Tiếp theo, tập tin tiêu đề của tôi myimgcom.h tập tin là:

int mysurf(int); 
void readme(); 

Tiếp theo, tập tin imagetest.go của tôi là:

package main 

import "fmt" 

// #include "myimgcom.h" 
import "C" 

func main() { 

    fmt.Printf("Invoking c library...\n") 
    C.mysurf(3) 

} 

tôi đang làm các lệnh sau:

gcc -O2 -c myimgcom.cpp -> runs successfully 
ar q libgb.a myimgcom.o -> runs successfully 
go build imagetest.go -> Here I get the following error: 

# command-line-arguments 
Undefined symbols for architecture x86_64: 
"_mysurf", referenced from: 
    __cgo_8db0969da00f_Cfunc_mysurf in imagetest.cgo2.o 
(maybe you meant: __cgo_8db0969da00f_Cfunc_mysurf) 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

Tôi nghĩ rằng vấn đề là liên kết các cấu hình pkg và cflags với cgo. Ai có thể đề nghị tôi làm thế nào tôi có thể giải quyết vấn đề? Tôi đang làm việc với Mac OS.

Trả lời

2

C++ không phải là C và các quy ước cuộc gọi khác nhau. Nó gần như không thể gọi C++ trực tiếp. Nếu bạn muốn gọi nó từ Go, trước tiên hãy làm một trình bao bọc C. Trong trường hợp của bạn bằng cách thêm "extern C" vào các khai báo hàm sẽ hoạt động.

extern "C" 
int mysurf(int myarg) 
{ 
// code here 
} 
+0

Vâng, hầu như. Anh/cô ấy nên _declare_ 'mysurf()' là 'extern" C "' và sau đó nó có thể định nghĩa nó bất cứ cách nào là cần thiết – user3159253

Các vấn đề liên quan