広告

ZxingをUE5.2で使えるようにしてみる(その5)

お久しぶりです。
その後いろいろPluginを作ったり、なんだかんだしているうちに解決したので対応方法を記載記載しておきます。

原因(おそらく)

おそらくなので確定ではないのですが、UEの場合Pluginとのデータのやり取りでstd系を使うと、
コピー時にヒープ領域にエラーなのかわからないですがゴミのデータができるらしく、それをデストラクタで削除しようとしてヒープ領域を壊していたようです。
Zxingでいうと、Resultクラス内にtextがstd::stringを返しているのでこいつをUE側で作成してもらってきているところが、ダメなところですね。

対策方法

ZxingはApache-2.0ライセンスなので改変しても問題ないでしょ!!
の精神で修正します。(修正でプログラムが壊れても自己責任でお願いします)

  1. Zxingのcore/src/ReadBarcode.hに関数を追加します。
    bool ReadBarcode(const ImageView& buffer, char getResoltStr[], const int strSizesize, const DecodeHints& hints = {});
  2. Zxingのcore/src/ReadBarcode.cppに関数を実装します。
    bool ReadBarcode(const ImageView& buffer, char getResoltStr[], const int strSizesize, const DecodeHints& hints)
    {
    auto info = FirstOrDefault(ReadBarcodes(buffer, DecodeHints(hints).setMaxNumberOfSymbols(1)));
    memset(getResoltStr, 0, strSizesize);
    strncpy_s(getResoltStr, strSizesize, info.text().c_str(), info.text().length());
    return info.error().type() == Error::Type::None;
    }


    日本語のコメントを書くとエラーになるのでこちらに軽くコメント
    1行目は画像解析結果を取得しているものです。
    DLL内で処理を完結させたいのでこの結果そのものを外に出すことはありません。
    2行目は念のために引数で受け取った文字列を格納する配列を初期化しています。
    3行目でコピー
    4行目はエラーかどうかを判定してエラー出ないときにtrueを返しているものです。
  3. ビルドする(リビルドを実行して確実にビルドされるようにした方が〇)
  4. dllとlibをPluginsにコピーする。

Zxing側の修正はここまでになります。
次にUE側の修正を行います。

  1. .slnを開いてZxingStaticLib.hのReadBarcodes関数を修正します。
    static FString ReadBarcodes(const FString& FilePath, const int resultStringSize = 1024);
  2. ZxingStaticLib.cppのReadBarcodesを修正します。
    長いので画像で割愛。

    大事なのは、画像を生成の部分
    newでchar配列を引数で受け取ったサイズで作成して、
    さっき作ったReadBarcodeでchar配列にデータを入れてもらう。
    問題なければFStringに変換して、配列はdelete[]で消す。
  3. ビルドして、実行する。
    うまくいけば左上に文字列が表示されてエラーにもならないはず。

    この状態だとシッピングでビルドしたときに確認ができないので適当にUIに表示させるようにすると・・・

    こんな感じになる
  4. パッケージングして実行する。
    エラーにならないはず!!!!!!

多分これでうまくいくはずです。
あとはカメラで動的に画像を読んでそれを文字列に変換できるようにする+Androidでも動くようにできればQR画像読み込んでどうにかできるようになるはず・・・・
先は長い・・・・・

コメント

タイトルとURLをコピーしました