分享
  1. 首页
  2. 文章

使用SWIG桥接Golang和Windows DLL

yushulx · · 3499 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

最近看了下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



有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:yushulx

查看原文:使用SWIG桥接Golang和Windows DLL

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
3499 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏