藉助Windows 10的普及,微軟開始推Universal應用開發。Universal應用其實和Android和iOS應用同樣,運行在sandbox中,在桌面環境裏exe不能雙擊運行。打成一個appx包以後能夠提交到Windows Store。任何運行Windows 10的設備均可以運行。那麼在開發的時候,現有的C/C++ SDK是否能夠兼容呢?答案是能夠的,不過會有一些限制。若是你想讓SDK兼容全部的設備,須要提供行x86, x64, arm三個版本DLL。我用Dynamsoft Barcode SDK作了試驗。html
參考原文:How to Create a Universal Barcode Reader on Windows 10 with C/C++ Legacy Codegit
做者:Xiao Linggithub
翻譯:yushulxwindows
在Windows 10中激活開發者模式。app
安裝Visual Studio 2015。visual-studio
編寫Hello World很簡單,能夠學習微軟的在線教程https://msdn.microsoft.com/en-us/library/windows/apps/dn996906.aspx。
spa
建立一個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