文档章节

使用SWIG桥接Golang和Windows DLL

yushulx
 yushulx
发布于 2015/11/24 09:47
字数 862
阅读 290
收藏 1

最近看了下Go语言,利用Dynamsoft Barcode SDK做了一个简单的Golang条形码扫描。这里分享下如何使用SWIG来快速封装底层C/C++接口。

参考原文:How to Use SWIG to Link Windows DLL with Golang

作者:Xiao Ling

翻译:yushulx

下载安装

如何使用SWIG实现Cgo封装

运行cmd.exe,设置GOPATH:

set GOPATH=f:\go-project
set DBR=<Dynamsoft Barcode Reader Directory>

创建一个package:

mkdir %GOPATH%\src\github.com\dynamsoftsamples\go-barcode-reader\dbr

从SDK目录中把DynamsoftBarcodeReaderx64.dll拷贝到%GOPATH%\src\github.com\dynamsoftsamples\go-barcode-reader\dbr\bin

接下来把头文件都拷贝到%GOPATH%\src\github.com\dynamsoftsamples\go-barcode-reader\dbr\include

创建dbr.c:

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "include/If_DBR.h"
 
__int64 GetFormat(int iIndex)
{
    __int64 llFormat = 0;
 
    switch(iIndex)
    {
    case 1:
        llFormat = OneD | QR_CODE | PDF417 |DATAMATRIX;
        break;
    case 2:
        llFormat = OneD;
        break;
    case 3:
        llFormat = QR_CODE;
        break;
    case 4:
        llFormat = CODE_39;
        break;
    case 5:
        llFormat = CODE_128;
        break;
    case 6:
        llFormat = CODE_93;
        break;
    case 7:
        llFormat = CODABAR;
        break;
    case 8:
        llFormat = ITF;
        break;
    case 9:
        llFormat = INDUSTRIAL_25;
        break;
    case 10:
        llFormat = EAN_13;
        break;
    case 11:
        llFormat = EAN_8;
        break;
    case 12:
        llFormat = UPC_A;
        break;
    case 13:
        llFormat = UPC_E;
        break;
    case 14:
        llFormat = PDF417;
        break;
    case 15:
        llFormat = DATAMATRIX;
        break;
    default:
        break;
    }
 
    return llFormat;
}
 
const char * GetFormatStr(__int64 format)
{
    if (format == CODE_39)
        return "CODE_39";
    if (format == CODE_128)
        return "CODE_128";
    if (format == CODE_93)
        return "CODE_93";
    if (format == CODABAR)
        return "CODABAR";
    if (format == ITF)
        return "ITF";
    if (format == UPC_A)
        return "UPC_A";
    if (format == UPC_E)
        return "UPC_E";
    if (format == EAN_13)
        return "EAN_13";
    if (format == EAN_8)
        return "EAN_8";
    if (format == INDUSTRIAL_25)
        return "INDUSTRIAL_25";
    if (format == QR_CODE)
        return "QR_CODE";
    if (format == PDF417)
        return "PDF417";
    if (format == DATAMATRIX)
        return "DATAMATRIX";
 
    return "UNKNOWN";
}
 
int decode_file(const char *pszImageFile)
{
    if (!pszImageFile)
    {
        return -1;
    }
 
  // const char *pszImageFile = "f:\\AllSupportedBarcodeTypes.tif";
    __int64 llFormat = (OneD | QR_CODE | PDF417 | DATAMATRIX);
    char pszBuffer[512] = {0};
 
    int iMaxCount = 0x7FFFFFFF;
    int iIndex = 0;
    ReaderOptions ro = {0};
    pBarcodeResultArray paryResult = NULL;
    int iRet = -1;
    char * pszTemp = NULL;
    char * pszTemp1 = NULL;
    unsigned __int64 ullTimeBegin = 0;
    unsigned __int64 ullTimeEnd = 0;
    size_t iLen;
    FILE* fp = NULL;
    int iExitFlag = 0;
 
    DBR_InitLicense("38B9B94D8B0E2B41DB1CC80A58946567");
 
    // Read barcode
    ullTimeBegin = GetTickCount();
    ro.llBarcodeFormat = llFormat;
    ro.iMaxBarcodesNumPerPage = iMaxCount;
    iRet = DBR_DecodeFile(pszImageFile, &ro, &paryResult);
    ullTimeEnd = GetTickCount();
 
    // Output barcode result
    pszTemp = (char*)malloc(4096);
    if (iRet != DBR_OK)
    {
        sprintf(pszTemp, "Failed to read barcode: %s\r\n", DBR_GetErrorString(iRet));
        printf(pszTemp);
        free(pszTemp);
        return 0;
    }
 
    if (paryResult->iBarcodeCount == 0)
    {
        sprintf(pszTemp, "No barcode found. Total time spent: %.3f seconds.\r\n", ((float)(ullTimeEnd - ullTimeBegin)/1000));
        printf(pszTemp);
        free(pszTemp);
        DBR_FreeBarcodeResults(&paryResult);
        return 0;
    }
 
    sprintf(pszTemp, "Total barcode(s) found: %d. Total time spent: %.3f seconds\r\n\r\n", paryResult->iBarcodeCount, ((float)(ullTimeEnd - ullTimeBegin)/1000));
    printf(pszTemp);
    for (iIndex = 0; iIndex < paryResult->iBarcodeCount; iIndex++)
    {
        sprintf(pszTemp, "Barcode %d:\r\n", iIndex + 1);
        printf(pszTemp);
        sprintf(pszTemp, "    Page: %d\r\n", paryResult->ppBarcodes[iIndex]->iPageNum);
        printf(pszTemp);
        sprintf(pszTemp, "    Type: %s\r\n", GetFormatStr(paryResult->ppBarcodes[iIndex]->llFormat));
        printf(pszTemp);
        pszTemp1 = (char*)malloc(paryResult->ppBarcodes[iIndex]->iBarcodeDataLength + 1);
        memset(pszTemp1, 0, paryResult->ppBarcodes[iIndex]->iBarcodeDataLength + 1);
        memcpy(pszTemp1, paryResult->ppBarcodes[iIndex]->pBarcodeData, paryResult->ppBarcodes[iIndex]->iBarcodeDataLength);
        sprintf(pszTemp, "    Value: %s\r\n", pszTemp1);
        printf(pszTemp);
        free(pszTemp1);
        sprintf(pszTemp, "    Region: {Left: %d, Top: %d, Width: %d, Height: %d}\r\n\r\n",
            paryResult->ppBarcodes[iIndex]->iLeft, paryResult->ppBarcodes[iIndex]->iTop,
            paryResult->ppBarcodes[iIndex]->iWidth, paryResult->ppBarcodes[iIndex]->iHeight);
        printf(pszTemp);
    }
 
    free(pszTemp);
    DBR_FreeBarcodeResults(&paryResult);
 
    return 0;
}

创建对应的dbr.i:

/* dbr.i */
 %module dbr
 %{
 /* Put header files here or function declarations like below */
 extern int decode_file(const char *pszImageFile);
 %}
 
 extern int decode_file(const char *pszImageFile);

生成dbr.go和dbr_wrapper.c:

swig -go -cgo -intgosize 32 dbr.i

这个时候看到的目录结构:

打开dbr.go,添加头文件和库文件路径:

#cgo CFLAGS: -I .
#cgo LDFLAGS: -L ./bin -lDynamsoftBarcodeReaderx64

切换路径到根目录%GOPATH%,编译安装:

go install github.com\dynamsoftsamples\go-barcode-reader\dbr

如果在package目录中,可以直接使用:

go install

这个时候会在%GOPATH%\pkg\windows_amd64\github.com\dynamsoftsamples\go-barcode-reader中生成一个包dbr.a

Windows上实现Golang条码扫描应用

创建%GOPATH%\github.com\dynamsoftsamples\go-barcode-reader\BarcodeReader\BarcodeReader.go:

package main
 
import (
  "github.com/dynamsoftsamples/go-barcode-reader/dbr"
  "os"
)
 
func main() {
  if len(os.Args) == 1 { // read the default image
    dbr.Decode_file("AllSupportedBarcodeTypes.tif")
  } else {
    dbr.Decode_file(os.Args[1])
  }
}

拷贝DynamsoftBarcodeReaderx64.dll%GOPATH%\bin

在根目录使用下面的命令行生成可执行文件:

go install github.com\dynamsoftsamples\go-barcode-reader\BarcodeReader

测试程序:

%GOPATH%bin\BarcodeReader.exe <barcode image>

参考

源码

https://github.com/dynamsoftsamples/go-barcode-reader


© 著作权归作者所有

共有 人打赏支持
yushulx
粉丝 26
博文 92
码字总数 52955
作品 0
杭州
私信 提问
Windows平台下Python使用swig调用C++

步骤0:swig简介 swig是一种可以将C++代码转换为多种脚本语言封装的工具,可以在swig官网www.swig.org下载,解压后将swig.exe的路径添加到环境变量path中即可使用swig 步骤1:准备C++代码 编...

月见樽
01/14
0
0
运行tensorflow报错

D:UsersAdministratorAppDataLocalProgramsPythonPython35python.exe D:/360c/shaozhechen-learntensorflow-master/learntensorflow/RNN_classification.py I c:tfjenkinshomeworkspacerelea......

sca7
2017/03/20
1K
0
C/C++ 和 Python混合编程

链接:https://www.zhihu.com/question/23003213/answer/56121859 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 #include int main(int argc, char *...

sirius_0
04/21
0
0
使用swig工具为go语言生成调用C、C++代码例子

swig开源项目(http://www.swig.org)为多种编程语言提供了相互访问的接口生成工具,这里面也包含了为go语言生成调用C、C++代码的功能。Go语言自带的cgo工具已经支持对C代码的调用,但对C++...

qinhui99
2012/06/29
0
5
简单的Windows Webcam应用:Barcode Reader

在Windows上用WinForm创建一个Webcam应用需要用到DirectShow。DirectShow没有提供C#的接口。如果要用C#开发,需要创建一个桥接DLL。Touchless SDK是一个免费开源的.NET库,对DirectShow进行了...

yushulx
2016/09/20
31
0

没有更多内容

加载失败,请刷新页面

加载更多

python中sort和sorted函数小结

L.sort(cmp=None, key=None, reverse=False) sorted(iterable, cmp=None, key=None, reverse=False) 这样看,sorted函数只比sort函数多一个iterable参数,其余没什么不同,iterable是一个迭代......

上官夏洛特
29分钟前
1
0
thinkphp 常用SQL执行语句总结

第一条:Db::tablera('vr_panomas')->where(['delete_time'=>0,'id'=>['in',$pids]])->field(['id'=>'id','post_thumb'=>'thumb','post_title'=>'title','post_tags'=>'tags','post_price'=>......

koothon
39分钟前
1
0
支付宝返回状态resultStatus意思

上一篇集成支付宝的时候,会有一些支付宝返回的resultStatus,具体意思是: 9000 订单支付成功 8000 正在处理中 4000 订单支付失败 6001 用户中途取消 6002 网络连接出错 还有memo,意思就是...

RainOrz
43分钟前
1
0
electron webview 页面加载事件顺序

1.did-start-loading 页面开始加载 2.load-commit 主页面文档加载 3.page-title-updated title 4.dom-ready 主页面 dom 加载完成 5.load-commit frame文档加载 6.did-frame-finish-load fram......

dubox
48分钟前
1
0
cron语法格式

Seconds Minutes Hours DayofMonth Month DayofWeek Year或 Seconds Minutes Hours DayofMonth Month DayofWeek...

JavaSon712
48分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部