私は、所有していない/保守していないドライバにC++からのioctl
コールを作成しています。きれいな "safe-ish"メカニズムがあるかどうかを調べています必要な醜い構造体の割り当てのいくつかに対処する。 IOCTL醜いC構造体割り当て用の最新のC++パターン
// IOCTL expects an instance of this structure "first"
typedef struct {
int param1;
int param2;
} s_ioctl_request;
//... followed by an instance of this. If attr_length
// is > sizeof(s_attr_header), more data is allowed to follow.
typedef struct {
uint32_t attr_length;
uint32_t attr_type;
} s_attr_header;
// Example that uses more data than just the header.
typedef struct {
s_attr_header hdr;
uint32_t attr_param;
} s_attr_type1;
// Another example.
typedef struct {
s_attr_header hdr;
uint32_t attr_param1;
uint32_t attr_param2;
} s_attr_type2;
を関与いくつかの構造のバージョンをスリム
はs_ioctl_request
が直ちにattr_length
をバイト単位外側構造体の大きさに設定されているs_attr_header
、またはそれを含む他の構造体、が続くことを必要とします。それはこれらの線に沿って何かを介して行われますioctl
のラッパー書くためC
で
、:私はと思ってい
int do_ugly_ioctl(int fd, int p1, int p2, s_attr_header * attr)
{
int res;
// Allocate enough memory for both structures.
s_ioctl_request *req = malloc(sizeof(*req) + attr->hdr.attr_length);
// Copy the 2nd, (variable length) structure after the first.
memcpy(((char*)req) + sizeof(*req), attr, attr->hdr.attr_length);
// Modify params as necessary
req->param1 = p1;
req->param2 = p2;
// Make the driver call, free mem, and return result.
res = ioctl(fd, SOME_IOCTL_ID, req);
free(req);
return res;
}
// Example invocation.
s_attr_type1 a1;
a1.hdr.attr_length = sizeof(a1);
a1.hdr.attr_type = 1;
do_ugly_ioctl(fd, 10, 20, &a1);
カップルのオプションは、以下のとおりです。
投現代のC++ - ismsはウィンドウの外にあり、私が上に示したものとまったく同じです。少なくとも私は
new[]
/delete[]
またはmalloc
/free
をやっていないよので- がのstd ::ベクトルのストレージを割り当て、結果として得られるのstd ::ベクトル::データ()ポインタで醜いキャストを行います。
s_attr_type*
ごとに独自の「特別な」構造体を使用する独自のラッパーメソッドを作成します。これは、「最も安全」と思われる、すなわち、ラッパー方法のユーザーがそれをねじ込む可能性が最も低いと思われる。そしてボーナスポイントは、パスバイリファレンスを許可します。
方法#3例:
は、それはC++に "それだけの価値" です - この問題に対する解決策をIZE:
int do_ugly_ioctl(fd, int param1, int param2, s_attr_type2& attr){ struct RequestData { s_ioctl_request ioreq; s_attr_type2 attr; }; RequestData r; r.ioreq.param1 = param1; r.ioreq.param2 = param2; r.attr = attr; r.attr.hdr.attr_length = sizeof(attr); // Might as well enforce this here. ioctl(fd, SOME_IOCTL_ID, (void*) &r); }
だから私はここにいくつかの質問があると思いますか? (エラーが発生しやすいC implに頼るのとは対照的に)。
私が方法#3またはそれに類似している場合は、
<type_traits>
でこの機能のテンプレートを作成し、最初のメンバーとしてs_attr_header
の構造体のみを受け入れることができますか?他にも素晴らしいアイデアはありますか?
Cラッパーには8行のコードが必要です。 C++ラッパーには10が必要です。私は多くの改善が見られません。 –
オプション2はstd :: vector内の割り当てを隠すだけなので、全く改善はありません。実際、オプション2はひどい解決策です。 –
@CareyGregoryすべてのC++プログラマーがベクトルの仕組みを知っているので、私はそれが隠されているとは言いません。それはカプセル化されたと呼ばれます。 – Jens