преобразование типов для структуры массива из c ++ в c - PullRequest
2 голосов
/ 22 июля 2011

У меня есть две библиотеки, от C ++ и C, соответственно:

lib A в C ++:

typedef struct { 
   char val[4096]; 
} AString;

lib B в C:

typedef struct STRING_TYPE{
   unsigned char *u1_list;
   signed int    i4_length;
} BString;

Если я не могу коснуться кода lib A & B, то есть не могу добавить оператор приведения в классе AString. Как конфертировать из AString в BString?

РЕДАКТИРОВАТЬ 1 : отдельная функция не определена:

AString as=XXX; // given variable 'as' to convert, 
unsigned char p[4096]; 
size_t const N = std::min(strlen(as.val), 4096); 
BString bs = { p, N }; 
std::copy( static_cast<unsigned char*>(&as.val[0]), static_cast<unsigned char*>(&as.val[N]), bs.u1_list ); 
// or use memcpy like: 
memcpy (bs.u1_list, as.val, N+1);
// then follows the part to use converted variable bs;
func(bs);

но код не имеет модульной структуры.

или еще:

РЕДАКТИРОВАТЬ 2 : по сути, EDIT_1, определить функцию,

void convert (AString& as, BString& bs)
{
    size_t const N = std::min(strlen(as.val), 4096);
    std::copy( static_cast<unsigned char*>(&as.val[0]), static_cast<unsigned char*>(&as.val[N]), bs.u1_list ); 
    // or use memcpy like: 
    memcpy (bs.u1_list, as.val, N+1);  
    bs.i4_length = N;            
}

но перед вызовом этой функции пользователь должен определить массив, например

AString as=XXX; // given variable 'as' to convert, 
unsigned char p[4096]; 
BString bs;
bs.u1_list = p; 
convert(as, bs);
// then follows the part to use converted variable bs;
func(bs);

Оба довольно неловко.

Нет ли какого-либо отдельного, отдельного способа сделать это?

Ответы [ 3 ]

7 голосов
/ 22 июля 2011

Примерно так:

BString convert(AString const& as)
{
   size_t const N = std::min(strlen(as.val), 4096);

   BString bs = { new unsigned char[N], N };
   std::copy(
      static_cast<unsigned char*>(&as.val[0]),
      static_cast<unsigned char*>(&as.val[N]),
      bs.u1_list
   );

   return bs;
}

Обязательно задокументируйте тот факт, что эта память теперь может быть утечка. Если честно, оба типа кажутся странными вещами в C ++; что не так с std::string?

4 голосов
/ 22 июля 2011

Если речь идет о C, вам нужно просто реализовать 2 процедуры, такие как AStringToBString (struct AString * a, struct BString * b) и BStringToAString (struct BString * b, struct AString * a)

Если речь идет о C ++, вы можете реализовать необходимые оболочки для мест, где вам нужно передать эти строки. Заставьте их просто работать с std :: string. Это называется шаблон дизайна фасада: http://en.wikipedia.org/wiki/Facade_pattern

int IamAwfulPureCProcedureThatDoesXXX(AString* a)
{
   ...
}
...
// what you do is:
int DoXXX(std::string const& a)
{
  AString aStr = MakeAStringFromStdString(a); // you have to implement it
  return IamAwfulPureCProcedureThatDoesXXX(aStr);
}
...
// then use as:
DoXXX("just a string");
0 голосов
/ 22 июля 2011

, поскольку никто не перечислил простой ответ, я буду

#include <string.h>

void makeBString(AString &foo, BString& bar) {
bar.u1_list=foo.val;
bar.i4_length=strlen(foo.val);
}
...