سؤال

ووفقا ل هنا ، وC إرادة مترجم لوحة من القيم عند كتابة هيكل إلى ملف ثنائي. كما في المثال في الرابط يقول، عند كتابة البنية مثل هذا:

struct {
 char c;
 int i;
} a;

وإلى ملف ثنائي، ومترجم وعادة ما تترك ل، حفرة غير المستخدمة اسمه بين شار وكثافة العمليات المجالات، لضمان أن حقل كثافة العمليات يتم محاذاة بشكل صحيح.

وكيف يمكن لي أن إنشاء نسخة طبق الأصل من ملف الإخراج ثنائي (ولدت في C)، وذلك باستخدام لغة مختلفة (في حالتي، جافا)؟

هل هناك طريقة تلقائية لتطبيق C الحشو في الناتج جافا؟ أو هل يجب أن تذهب من خلال وثائق المترجم لنرى كيف يعمل (المترجم هو ز ++ بالمناسبة).

هل كانت مفيدة؟

المحلول

وهذا صحيح ليس فقط عند الكتابة إلى الملفات، ولكن أيضا في الذاكرة. وهذه هي حقيقة أن البنية هو مبطن في الذاكرة، الذي يؤدي إلى الحشو تظهر في الملف، إذا هو مكتوب البنية من البايت بواسطة بايت.

ومن بشكل عام من الصعب جدا تكرار بيقين مخطط الحشو المحدد، على الرغم من أنني أعتقد أن بعض الاستدلال تحصل بعيدا جدا. كما أنه يساعد إذا كان لديك إعلان البنية، لتحليلها.

وعادة، حقول وسيجري التوفيق شار أكبر من واحد بحيث بدايتها تعويض داخل هيكل من مضاعفات حجمها. وهذا يعني أن shorts بشكل عام على حتى إزاحة (القسمة على 2، على افتراض sizeof (short) == 2)، في حين doubles سيكون على إزاحة قسمة بنسبة 8، وهلم جرا.

<القوي> UPDATE : لأنها لأسباب مثل هذه (وأيضا أسباب لها علاقة endianness) أنه بشكل عام فكرة سيئة لتفريغ البنيات كلها إلى الملفات. فمن الأفضل أن تفعل ذلك المجال من قبل الميدان، كما يلي:

put_char(out, a.c);
put_int(out, a.i);

وعلى افتراض أن وظائف put الكتابة فقط البايتات اللازمة للقيمة، وهذا سوف تصدر نسخة والحشو أقل من البنية إلى الملف، حل المشكلة. ومن الممكن أيضا لضمان السليم، والمعروف، بايت يأمر من خلال كتابة هذه الوظائف وفقا لذلك.

نصائح أخرى

لا تفعل هذا، هو هش، وسوف يؤدي إلى التوافق وendianness البق.

لالبيانات الخارجية هو أفضل بكثير لتحديد بشكل واضح شكل من حيث بايت والكتابة وظائف صريحة للتحويل بين الشكل الداخلي والخارجي، وذلك باستخدام التحول والأقنعة (وليس الاتحاد!).

<اقتباس فقرة>   

هل هناك طريقة تلقائية لتطبيق C   الحشو في الناتج جافا؟ أو لا بد لي   للذهاب من خلال وثائق مترجم   لنرى كيف يعمل (المحول البرمجي   ز ++ بالمناسبة).

ولا. بدلا من ذلك، يمكنك تحديد صراحة تنسيق البيانات / الاتصال وتنفيذ تلك المواصفات، بدلا من الاعتماد على تفاصيل تنفيذ مترجم C. أنت لن تحصل حتى على نفس الناتج من المجمعين C مختلفة.

لقابلية التشغيل البيني، أن ننظر في الدرجة ByteBuffer.

وأساسا، يمكنك إنشاء منطقة عازلة من حجم معين، وطرح () المتغيرات من أنواع مختلفة في مواقع مختلفة، ومن ثم استدعاء مجموعة () في نهاية لاسترداد تمثيل البيانات "الخام":

ByteBuffer bb = ByteBuffer.allocate(8);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(0, someChar);
bb.put(4, someInteger);
byte[] rawBytes = bb.array();

ولكن الامر متروك لك للعمل فيها لوضع padding-- أي عدد البايتات لتخطي بين المواقف.

لقراءة البيانات المكتوبة من C، فإنك عموما <م> التفاف () وByteBuffer حول بعض مجموعة البايت التي كنت قد قرأت من ملف.

في حالة أنه من المفيد، لقد كتبت أكثر على ByteBuffer .

وهناك طريقة يدوية من القراءة / الكتابة البنيات C في جاوة هو استخدام فئة javolution البنية (انظر HTTP: // شبكة الاتصالات العالمية .javolution.org ). وهذا لن تساعدك مع الحشو تلقائيا / مواءمة البيانات الخاصة بك، ولكن لا تجعل العمل مع البيانات الخام التي عقدت في ByteBuffer أكثر ملاءمة. إذا كنت لم تكن مألوفة مع javolution، انها تستحق نظرة كما هناك الكثير من الاشياء باردة أخرى في ذلك أيضا.

وهذا الثقب هو شكلي، مترجم ديه مفاتيح لمحاذاة البنيات التي كتبها 1/2/4/8 بايت.

ولذا فإن السؤال الأول هو: ما هي محاذاة بالضبط هل تريد محاكاة

ومع جافا، يتم تحديد حجم أنواع البيانات بواسطة مواصفات اللغة. على سبيل المثال، وهو نوع byte هو 1 بايت، short هو 2 بايت، وهلم جرا. وهذا بخلاف C، حيث حجم كل نوع هو تعتمد على الهندسة المعمارية.

لذلك، سيكون من المهم أن نعرف كيفية تنسيق ملف ثنائي لكي تكون قادرا على قراءة الملف إلى جاوة.

قد يكون من الضروري اتخاذ خطوات من أجل التأكد من أن الحقول حجم معين، لمراعاة الفروق في مترجم أو الهندسة المعمارية. ذكر محاذاة يبدو أن تشير إلى أن الملف الناتج سوف تعتمد على الهندسة المعمارية.

ويمكنك أن تحاول preon :

<اقتباس فقرة>   

وPreon هي مكتبة جافا لالترميز بناء على بيانات مضغوط BITSTREAM في   التعريفي (الشرح القائم) الطريقة. أعتقد JAXB أو السبات، ولكن بعد ذلك لثنائي   ترميز البيانات.

وأنه يمكن التعامل مع الكبير / البيانات endian ليتل الثنائية، والمحاذاة (الحشو) وأنواع رقمية مختلفة على طول غيرها من الميزات. ومن مكتبة لطيفة جدا، وأنا أحب ذلك كثيرا جدا

وبلدي 0.02 $

وأنا أوصي مخازن بروتوكول للبالضبط هذه المشكلة.

وكما فهمت، أنت تقول أنك لا تتحكم في إخراج برنامج C. عليك أن تأخذ ذلك على النحو المبين.

وكذلك الحال بالنسبة لديك لقراءة هذا الملف بحثا عن بعض مجموعة محددة من الهياكل، أو هل لديك حل لهذا في الحالة العامة؟ أعني، هي المشكلة التي قال أحدهم، "هنا الملف الذي تم إنشاؤه من قبل برنامج X، لديك لقراءتها في جافا"؟ أو أنها لا تتوقع برنامج جافا لقراءة شفرة المصدر C، والعثور على تعريف بنية، ومن ثم قراءتها في جافا؟

إذا كنت قد حصلت على ملف معين لقراءة، والمشكلة ليست في الحقيقة صعبة للغاية. إما عن طريق مراجعة المواصفات مترجم C أو من خلال دراسة الملفات سبيل المثال، معرفة من أين الحشو هو. ثم على الجانب جافا، قراءة الملف ك دفق بايت، وبناء القيم تعلمون قادمون. في الأساس كنت أكتب مجموعة من الوظائف لقراءة العدد المطلوب من وحدات البايت من InputStream وتحويلها إلى نوع البيانات المناسب. مثل:

int readInt(InputStream is,int len)
  throws PrematureEndOfDataException
{
  int n=0;
  while (len-->0)
  {
    int i=is.read();
    if (i==-1)
      throw new PrematureEndOfDataException();
    byte b=(byte) i;
    n=(n<<8)+b;
  }
  return n;
}

يمكنك تغيير التعبئة على الجانب ج لضمان أن يتم استخدام أي الحشو، أو بدلا من ذلك يمكنك أن تبحث في تنسيق الملف الناتج في محرر عرافة ليسمح لك لكتابة محلل في جاوة أن يتجاهل بايت التي هي الحشو.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top