2022年1月24日月曜日

Vcpkg autolink を無効にする忘備録

vcpkg で、AutoLinkが有効になっている、明後日の方向のライブラリにリンクしてしまい、不可解なエラーに悩まされます。

なので、AutoLink を無効にしたい。

*.vcxprj を開きます。
PropertyGroup を検索し、以下の設定を追加します。
  <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='UnicodeRelease|x64'">
    <VcpkgAutoLink>false</VcpkgAutoLink>
  </PropertyGroup>
  <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='UnicodeRelease|Win32'">
    <VcpkgAutoLink>false</VcpkgAutoLink>
  </PropertyGroup>

UnicodeRelease|x64 等は、自分のビルド構成と合わせるようにしましょう。
以上。

vcpkg BuildTool を古いバージョンに変更備忘録

書いておかないと、忘れて調べ直す事になるので・・・
vcpkg でビルドをすると 最新バージョンのVisual Studio が使用されるようになって、それでは困る場合があるので、その設定の仕方。

vcpkg/triplets ディレクトリ下のファイルに
arm64-windows.cmake
arm-uwp.cmake
x64-linux.cmake
x64-osx.cmake
x64-uwp.cmake
x64-windows.cmake
x64-windows-static.cmake
x86-windows.cmake
とファイルが並んでいます。
その x64-windwos.cmake と x86-windows.cmake に対して
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE dynamic)
set(VCPKG_PLATFORM_TOOLSET "v140")
set(VCPKG_DEP_INFO_OVERRIDE_VARS "v140")
というように VCPKG_PLATFORM_TOOLSET, VCPKG_DEP_INFO_OVERRIDE_VARS を追加し、TOOLSET のバージョンを指定します。
以上。

なんか、一時的にブロガーのポストができなくなって、前のポストを一旦削除して、作り直しました。

C++データを16進表記相互変換

ちょくちょくデータを暗号化して16進数表記文字列に変換して保存し、保存された16進表記文字列をデータに復元する事をやるので、忘備録として記録する事に。こういう、ちょっとしたものでも、書こうと思ったら時間を取られる。
#include <string>
#include <iostream>

static int atob( int c ) {
  static const unsigned char btbl[] = {
    // 0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  0
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  1
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  2
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05,  0x06, 0x07,  0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  3
    0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,  0x0F, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  4
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  5
    0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,  0x0F, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  6
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  7
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  8
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  9
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  A
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  B
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  C
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  D
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  E
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   //  F
  };
  return btbl[ c ];
}


//! 16進文字列から unsigned char 配列への変換
/*
  @note 16進文字列は、0-9, A-F のみを利用した表記で
    1バイトを2文字で表記しているものとする。16進を示す 0x 等の
    接頭辞は含まれていない。
*/
void hexstr2str(
  const std::string& src,
  std::string& dst
) {
  dst.resize( (src.size() + 1) / 2 );
  for(size_t i = 0; i < src.size(); i++) {
    if( (i & 1) != 0 ) {
      dst[ i / 2 ] |= atob( src[i] );
    } else {
      dst[ i / 2 ] = atob( src[i] ) << 4;
    }
  }
}

//! unsigned char 配列から 16進文字列への変換
/*!
  @note 16進文字列は、0-9, A-F のみを利用した表記で
    1バイトを2文字で表記したものに変換される。16進を示す 0x 等の
    接頭辞は含まない。
*/
void str2hexstr(
  const std::string&  src,
  std::string&        dst
) {
  static const char atbl[] = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
  };
  dst.resize( src.size() * 2 );
  for( size_t i = 0; i < src.size(); i++ ) {
    dst[i*2  ] = atbl[ ((src[i] >> 4) & 0x0F) ]; // & 0x0F しないと算術シフトでアウトでした
    dst[i*2+1] = atbl[ (src[i] & 0x0F) ];
  }
}

int main() {
  std::string src = "Hello world!";
  std::string hex, dst;
  std::cout << src << std::endl;
  str2hexstr( src, hex );
  std::cout << hex << std::endl;
  hexstr2str( hex, dst );
  std::cout << dst << std::endl;
  return 0;
}

結果

Hello world!
48656C6C6F20776F726C6421
Hello world!
2022/01/14 追記: str2hexstr のコメントに書いたバグ修正をしました

2022年1月7日金曜日

JNI GetMethodID に指定するタイプ文字列 忘備録

JNI で Java method id を取得する GetMethodID 関数に渡す文字列のドキュメントが見つからないので、忘備録として記す事に

まず、Primitive Type の表

タイプ文字列Primitive Type
V void
Z boolean
B byte
C char
S short
I int
J long
F float
D double


クラスのタイプ文字列は、
 Ljava/lang/String;
というように L で始まり、class URIを書いて ; で閉じる

配列の場合は、
 [I
というように [ で始まり、タイプ文字列を書く
上記の場合 int [] に対応する

関数表記は
()V
([Ljava/lang/String;)I
というように、 ( 引数 ) 返り値 というように表記する
以上