1. 新建工程,选择如下红色框
2. 接着选中如下
3. 接着如下
4. 右键,选择“添加引用”,添加图像库
5. 把如下内容拷贝替换Module1.vb中的内容
Imports System.Drawing
Module Module1
Public Declare Function InitPCBModels Lib “pcb.dll” (ByVal data As String) As Long
Public Declare Function DetectPCBMain Lib “pcb.dll” (ByVal data As Long, ByVal height As Integer, ByVal width As Integer, ByVal offset As Integer, ByVal data As String) As Long
Public Structure ImageInfo
Public imageW As Integer
Public imageH As Integer
Public offset As Integer
Public imageDataPtr As IntPtr
End Structure
Public Function GetImageDataPtr(imagePath As String) As ImageInfo
Dim testImage As Bitmap
testImage = New Bitmap(imagePath)
Dim hBitmap As IntPtr
hBitmap = testImage.GetHbitmap()
Dim imgH As Integer
imgH = testImage.Height
Dim imgW As Integer
imgW = testImage.Width
' Lock the bitmap's bits.
Dim bitmapData As Imaging.BitmapData
Dim rect As New Rectangle(0, 0, imgW, imgH)
'Dim format As Imaging.PixelFormat
'format = testImage.PixelFormat
'bitmapData = testImage.LockBits(rect, Imaging.ImageLockMode.ReadWrite, format)
bitmapData = testImage.LockBits(rect, Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format24bppRgb)
Dim img_stride As Integer
Dim offset As Integer
img_stride = bitmapData.Stride
offset = img_stride - imgW * 3
' Get the address of the first line.
Dim bmpDataPtr As IntPtr = bitmapData.Scan0
' Unlock the bits.
testImage.UnlockBits(bitmapData)
Dim imageInfo As ImageInfo
imageInfo.imageW = imgW
imageInfo.imageH = imgH
imageInfo.offset = offset
imageInfo.imageDataPtr = bmpDataPtr
Return imageInfo
End Function
Sub Main()
Dim modelPath As String
'模型所在路径, 对应SDK目录下xxx/SDK/models,即包含以encrypted_开头的文件所在路径
'modelPath = "D:/shenjh-work/coding/vbcallcpp/models"
modelPath = "D:/output"
'该初始化只需初始化一次,后面就不需要调用
Dim retInit As Long = InitPCBModels(modelPath)
MsgBox("InitPCBModels 返回结果:" & retInit)
'测试图片的路径,这里就是模拟相机传图
Dim srcImagePath As String
srcImagePath = "Z:/1/in_src_rgb.bmp"
Dim imageInfo As ImageInfo = GetImageDataPtr(srcImagePath)
'tempString 可传,也可不传
Dim tempString As String
'pcbResult返回的图片检测结果,0代表OK,1代表NG
Dim pcbResult As Long
pcbResult = DetectPCBMain(imageInfo.imageDataPtr, imageInfo.imageH, imageInfo.imageW, imageInfo.offset, tempString)
MsgBox("DetectPCBMain 返回结果:" & pcbResult)
End Sub
End Module
VB调用C++库最核心的代码就是下面这一段,不过需要注意,VB与C++数据类型要对应,这里VB中的 String 对应 C++ 中的 char*
Public Declare Function InitPCBModels Lib “pcb.dll” (ByVal data As String) As Long
6. 接着修改如下内容
7. 改完后,应该如下图
8. 接着接着右键callCppDll,点击“重新生成”,如下
9. 生成完打开其所生成的exe路径,如下红色框
10. 把需要用的依赖库拷贝到 callCppDll.exe 路径下就可运行
11. 注意,由于是VB读图,传到底层Opencv,底层需要判断下,传到底层构建的图片会不一样,底层构建应与下面代码构建一致。另外,由于上层传的指针,所以底层在操作时往往会检测结果不一样,解决版本就是构建好 cv::Mat 就把构建的 in_src_rgb.clone() 用于后面的处理。其实不光VB传底层,底层要clone,同是C++相互调用,往往也需要构建好 cv::Mat 后进行 .clone()。
int step = 0;
if (input_offset != 0)
{
step = ((input_width * 3 * 8 + 31) / 32) * 4;
}
cv::Mat in_src_rgb(input_heiht, input_width, CV_8UC3, input_src, step);
上面 input_offset 就是 VB 读图传下来的,对应上面代码
imageInfo.offset = offset