标签:
借助Windows 10的普及,微软开始推Universal应用开发。Universal应用其实和Android和iOS应用一样,运行在sandbox中,在桌面环境里exe不能双击运行。打成一个appx包之后可以提交到Windows Store。任何运行Windows 10的设备都可以运行。那么在开发的时候,现有的C/C++ SDK是否可以兼容呢?答案是可以的,不过会有一些限制。如果你想让SDK兼容所有的设备,需要提供行x86, x64, arm三个版本DLL。我用Dynamsoft Barcode SDK做了试验。
参考原文:How to Create a Universal Barcode Reader on Windows 10 with C/C++ Legacy Code
作者:Xiao Ling
翻译:yushulx
在Windows 10中激活开发者模式。
编写Hello World很简单,可以学习微软的在线教程https://msdn.microsoft.com/en-us/library/windows/apps/dn996906.aspx。
创建一个Universal应用。
在 MainPage.xaml中添加Image, Button和TextBlock:
<ScrollViewer Grid.Row="1" VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto" VerticalAlignment="Top"> <StackPanel> <Grid x:Name="Image" Margin="0,0,0,5" VerticalAlignment="Top"> <Image x:Name="PreviewImage" HorizontalAlignment="Left" VerticalAlignment="Top" MaxWidth="600"/> </Grid> <StackPanel Orientation="Horizontal" Margin="0, 0, 0, 5" VerticalAlignment="Top"> <Button x:Name="button" Margin="0, 0, 5, 0" Click="button_Click" VerticalAlignment="Top"> <Viewbox MaxHeight="40" MaxWidth="40"> <SymbolIcon Symbol="OpenFile"/> </Viewbox> </Button> <TextBlock x:Name="BarcodeResults" Margin="0,0,0,10" TextWrapping="Wrap" Text="Results:" Height="600" Width="300" VerticalAlignment="Stretch" HorizontalAlignment="Left" /> </StackPanel> </StackPanel> </ScrollViewer>
使用FileOpenPicker来加载文件:
FileOpenPicker^ picker = ref new FileOpenPicker(); picker->FileTypeFilter->Append(".bmp"); picker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
从WriteableBitmap中获取图像数据的C++指针:
byte* GetPointerToPixelData(IBuffer^ pixelBuffer, unsigned int *length) { if (length != nullptr) { *length = pixelBuffer->Length; } // Query the IBufferByteAccess interface. ComPtr<IBufferByteAccess> bufferByteAccess; reinterpret_cast<IInspectable*>(pixelBuffer)->QueryInterface(IID_PPV_ARGS(&bufferByteAccess)); // Retrieve the buffer data. byte* pixels = nullptr; bufferByteAccess->Buffer(&pixels); return pixels; }
使用DecodeBuffer检测图像数据。因为没有对应的接口,需要自己构造数据 (BITMAPINFOHEADER + Image data)。BITMAPINFOHEADER为40个字节,再加上实际的数据:
char *total = (char *)malloc(len + 40); BITMAPINFOHEADER bitmap_info = { 40, width, height, 0, 32, 0, len, 0, 0, 0, 0 }; memcpy(total, &bitmap_info, 40); char *data = total + 40; memcpy(data, buffer, len);
获取barcode结果:
iRet = reader.DecodeBuffer((unsigned char*)total, len + 40); // Output barcode result pszTemp = (char*)malloc(4096); if (iRet != DBR_OK) { sprintf(pszTemp, "Failed to read barcode: %s\r\n", DBR_GetErrorString(iRet)); free(pszTemp); return nullptr; } pBarcodeResultArray paryResult = NULL; reader.GetBarcodes(&paryResult);
接下来就是要想办法把C String转换成Platform::String^。StackOverflow上可以找到解答:
results = ref new Array<String^>(paryResult->iBarcodeCount); for (iIndex = 0; iIndex < paryResult->iBarcodeCount; iIndex++) { sprintf(pszTemp, "Barcode %d:\r\n", iIndex + 1); sprintf(pszTemp, "%s Page: %d\r\n", pszTemp, paryResult->ppBarcodes[iIndex]->iPageNum); sprintf(pszTemp, "%s Type: %s\r\n", pszTemp, GetFormatStr(paryResult->ppBarcodes[iIndex]->llFormat)); 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, "%s Value: %s\r\n", pszTemp, pszTemp1); // http://stackoverflow.com/questions/11545951/how-to-convert-from-char-to-platformstring-c-cli std::string s_str = std::string(pszTemp); std::wstring wid_str = std::wstring(s_str.begin(), s_str.end()); const wchar_t* w_char = wid_str.c_str(); OutputDebugString(w_char); barcode_result = ref new String(w_char); results->set(iIndex, barcode_result); free(pszTemp1); }
从<Dynamsoft Barcode SDK>\Redist\C_C++目录拷贝DynamsoftBarcodeReaderx86.dll到DynamsoftBarcodeReader\Debug\DynamsoftBarcodeReader\AppX目录。
现在可以通过CTRL+F5或者菜单来运行程序了。
Universal Barcode Reader 截图:
开发Universal应用的时候,有些C的接口是受到限制的,因此SDK中提供的DecodeFile接口用不了,因为需要调用fopen。具体限制可以参考CRT functions not supported in Universal Windows Platform apps。
SDK中提供的QR二维码解码失效。
用DecodeBuffer的时候只能使用BMP图像。
https://github.com/dynamsoftsamples/universal-windows-barcode-reader
Windows Universal App中集成C/C++ DLL
标签:
原文地址:http://my.oschina.net/yushulx/blog/517142