4

UUID 値を SQL SERVER 列から (Qt Sql モジュール経由で) QUID オブジェクトにバインドします。その後、char* をパラメーターとして受け取る assign 関数を使用して、社内の uuid オブジェクトに割り当てる必要があります。

QUID はいくつかの char* をパブリック メンバーとして公開するため、いくつかの char * QUID のメンバーを使用して 16 バイトの char * を構築する必要があります。

つまり、次をコピーします。

char buff0;
char buff1;
char buff2[2];
char buff3[4];
char buff4[8];

中身

char final[16];

私は memcpy を使用して、このタスクを次のように実行しました。

int accu = 0;    
memcpy(final, &buff0, sizeof(buff0)); 
accu += sizeof(buff1);
memcpy(final+accu, &buff1, sizeof(buff1));
accu += sizeof(buff2);
memcpy(final+accu, buff2, sizeof(buff2));
accu += sizeof(buff3);
memcpy(final+accu, buff3, sizeof(buff3));
accu += sizeof(buff4);
memcpy(final+accu, buff4, sizeof(buff4));

しかし、この方法は実際には読みやすく、保守可能ではありません。このタスクを実行するためのよりエレガントな方法を探しています。エレガントとは、コード行や演算が少ないことを意味します。

4

5 に答える 5

2

これは C++11 STL バージョンです。

char* out = final;
out = std::copy_n(&buff0, 1, out);
out = std::copy_n(&buff1, 1, out);
out = std::copy_n(buff2, 2, out);
out = std::copy_n(buff3, 4, out);
out = std::copy_n(buff4, 8, out);
于 2012-10-23T20:13:51.513 に答える
2

1 つのオプションは、共用体を使用して、どちらの定義も交換可能に使用できるようにすることです。

于 2012-10-23T19:46:32.223 に答える
1

x86 アセンブリを使用する

;; FASM/NASM syntax
MOV    esi, final
MOVZX  eax, byte [buf0]
MOVZX  ebx, byte [buf1]
MOVZX  ecx, word [buf2]
MOV    edx, dword [buf3] 
MOV    byte [esi], al
MOV    byte [esi+1], bl
MOV    eax, dword [buf4]
MOV    ebx, dword [buf4+4]
MOV    word [esi+2], cx
MOV    dword [esi+4], edx
MOV    dword [esi+8], eax
MOV    dword [esi+12], ebx

または、buf のすべてのメモリが (パディングなしで) 線形に割り当てられ、1 つの memcpy だけを使用するというワイルドな仮定を作成するのはどうですか?

memcpy(final, buf0, 16)
于 2012-10-23T19:49:13.953 に答える
1

copy()まず、以下は、静的にチェックされた関数を作成する C++ 2011 ソリューションです。引数として s と scharの配列を受け入れ、渡される最初の配列を満たすためにchar正確に s の量を追加する必要があります。charもちろん、静的チェックは必要に応じて削除できます。元のバージョンには、いくつかのタイプミスと脱落がありました。

#include <algorithm>
#include <iostream>
#include <iterator>

int constexpr size(char const&) { return 1; }
template <int Size>
int constexpr size(char const(&)[Size]) { return Size; }
template <typename T0, typename... T>
int constexpr size(T0 const& arg0, T const&... args) {
    return size(arg0) + size(args...);
}

char* copy_intern(char* to, char c) { *to = c; return ++to; }
template <int Size>
char* copy_intern(char* to, char const (&array)[Size]) {
    return std::copy(array, array + Size, to);
}

template <typename T0, typename... T>
char* copy_intern(char* to, T0 const& arg0, T const&... args) {
    return copy_intern(copy_intern(to, arg0), args...);
}

template <int Total, typename... T>
void copy(char (&to)[Total], T const&... args)
{
    static_assert(Total == size(args...), "wrong argument size");
    copy_intern(to, args...);
}

int main()
{
    char buff0    = 'a';
    char buff1    = 'b';
    char buff2[2] = { 'c', 'd' };
    char buff3[4] = { 'e', 'f', 'g', 'h' };
    char buff4[8] = { 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' };
    char final[16];

    copy(final, buff0, buff1, buff2, buff3, buff4);
    *std::copy(final, final + 16,
               std::ostreambuf_iterator<char>(std::cout)) = '\n';
}

copy_intern()最初の 2 つの関数を C++ 2003 でも使用して、引数の型とサイズを推測できることに注意してください。つまり、これらの関数を使用すると、適切と見なされるように名前が変更される可能性があり、少なくともサイズを自動的に取得するものを取得できます。

    char* tmp = final;
    tmp = copy_intern(tmp, buff0);
    tmp = copy_intern(tmp, buff1);
    tmp = copy_intern(tmp, buff2);
    tmp = copy_intern(tmp, buff3);
    tmp = copy_intern(tmp, buff4);
于 2012-10-23T19:57:59.423 に答える
1
memcpy(&final[0], &buff0, 1);
memcpy(&final[1], &buff1, 1);
memcpy(&final[2], &buff2[0], 2);
memcpy(&final[4], &buff3[0], 4);
memcpy(&final[8], &buff4[0], 8);
于 2012-10-23T19:50:09.813 に答える