PDA

View Full Version : سوال: marshaling



qasemf
پنج شنبه 28 اسفند 1399, 13:24 عصر
سلام کسی میدونه دلیل این پیغام خطا چیه؟153159
زمانی که usb وصل سیستم میشه باید پیغام بده که مثلا نام این usb فلان هست و غیره..
حالا وقتی برنامه رو ران میکنم به محض وصل کردن فلش به سیستم، برنامه متوقف میشه
راستی مفهوم مارشالینگ یعنی چی؟

the king
پنج شنبه 28 اسفند 1399, 22:41 عصر
سلام کسی میدونه دلیل این پیغام خطا چیه؟153159
زمانی که usb وصل سیستم میشه باید پیغام بده که مثلا نام این usb فلان هست و غیره..
حالا وقتی برنامه رو ران میکنم به محض وصل کردن فلش به سیستم، برنامه متوقف میشه
راستی مفهوم مارشالینگ یعنی چی؟
در NET. یک ماشین مجازی هست و یک محیط مدیریت شده (Managed) که از محیط بیرون از NET. (محیط Unmanaged) جدا است.
اگر بخواهید داده بین این دو محیط رد و بدل کنید، داده باید به یک قالب قابل انتقال تبدیل بشه تا بشه انتقالش داد، به این تبدیل داده که برای انتقال مناسبش می کنه Marshalling میگن.

حالا بریم سراغ بحث انتقال داده اون struct مورد نظر.
وقتی یک structure در محیط NET. تعریف میشه، باید یکسری فیلد کنار هم در حافظه اش قرار بگیرند، پس باید موقعیت فیلد های داخلش در حافظه اون structure مشخص بشه.
مثلا اینکه A باید اول قرار بگیره یا B، البته بحث چینش پیچیده تر از اینه که اول A باشه یا B ولی در همین حد به موضوع مربوطه.

public struct MyStruct
{
public int A;
public int B;
}


برای مشخص کردن موقعیت این فیلد ها سه حالت وجود داره، Auto و Explicit و Sequential که ییشفرض هم Auto است.
Auto یعنی بصورت خودکار موقعیت آیتم ها در حافظه مشخص بشه، یعنی برنامه نویس اصلا برایش مهم نیست که با چه ترتیبی ثبت میشن.
Explicit یعنی خود برنامه نویس صریحا موقعیت هر فیلد رو تعیین کنه.
Sequential یعنی با همون ترتیب نوشتن کد ثبت بشن.

مادامی که از اون structure فقط در داخل محیط NET. (یعنی محیط Managed) استفاده می کنید همون حالت Auto کاملا مناسبه و در حقیقت برای کد #C شما اهمیتی نداره که کجا و چطور ذخیره میشه. ولی اگر بخواهید به محیط بیرون از NET. (یعنی محیط Unmanaged) ارتباط اش بدید، Marshalling روی موقعیت فیلد ها حساس میشه.
فرضا در این struct من مشخص می کنم که میخوام به همون ترتیب نوشتن (اول A و بعد B) باشه :

using System.Runtime. InteropServices;

[StructLayout (LayoutKind.Sequential)]
public struct MyStruct
{
public int A;
public int B;
}


یا ممکنه صریحا مشخص کنم که اول B در Offset صفر (شروع حافظه ثبت بشه) و بعد A چهار بایت بعدش ثبت بشه :

using System.Runtime. InteropServices;

[StructLayout (LayoutKind.Explicit)]
public struct MyStruct
{
[FieldOffset(4)]
public int A;

[FieldOffset(0)]
public int B;
}


حالا مشکل کد شما اینه که DevBroadcastVolume در حالت Auto است، Marshal نمیدونه اگر بخواد با محیط Unmanaged تبادل داده کنه فیلد های داخل DevBroadcastVolume رو باید کجای حافظه پیدا کنه، ترتیب و موقعیت شون مشخص نیست. الان نمیدونه Mask چند بایت از شروع حافظه اون IntPtr فاصله داره. نمیدونه vol.Mask کجای حافظه است. برای همین نمیتونه Marshalling رو انجام بده.

حداقل کاری که می توانید بکنید اینه که جایی که اون struct ئه DevBroadcastVolume تعریف شده بروید و در سطر قبل از struct با [StructLayout (LayoutKind.Sequential)] حالت Sequential رو انتخاب کنید تا Marshal متوجه بشه که میخواهید با همون ترتیب نوشتن فیلد ها در حافظه قرار بگیرند.

SajjadKhati
جمعه 29 اسفند 1399, 01:20 صبح
در NET. یک ماشین مجازی هست و یک محیط مدیریت شده (Managed) که از محیط بیرون از NET. (محیط Unmanaged) جدا است.
اگر بخواهید داده بین این دو محیط رد و بدل کنید، داده باید به یک قالب قابل انتقال تبدیل بشه تا بشه انتقالش داد، به این تبدیل داده که برای انتقال مناسبش می کنه Marshalling میگن.

حالا بریم سراغ بحث انتقال داده اون struct مورد نظر.
وقتی یک structure در محیط NET. تعریف میشه، باید یکسری فیلد کنار هم در حافظه اش قرار بگیرند، پس باید موقعیت فیلد های داخلش در حافظه اون structure مشخص بشه.
مثلا اینکه A باید اول قرار بگیره یا B، البته بحث چینش پیچیده تر از اینه که اول A باشه یا B ولی در همین حد به موضوع مربوطه.

public struct MyStruct
{
public int A;
public int B;
}


برای مشخص کردن موقعیت این فیلد ها سه حالت وجود داره، Auto و Explicit و Sequential که ییشفرض هم Auto است.
Auto یعنی بصورت خودکار موقعیت آیتم ها در حافظه مشخص بشه، یعنی برنامه نویس اصلا برایش مهم نیست که با چه ترتیبی ثبت میشن.
Explicit یعنی خود برنامه نویس صریحا موقعیت هر فیلد رو تعیین کنه.
Sequential یعنی با همون ترتیب نوشتن کد ثبت بشن.

مادامی که از اون structure فقط در داخل محیط NET. (یعنی محیط Managed) استفاده می کنید همون حالت Auto کاملا مناسبه و در حقیقت برای کد #C شما اهمیتی نداره که کجا و چطور ذخیره میشه. ولی اگر بخواهید به محیط بیرون از NET. (یعنی محیط Unmanaged) ارتباط اش بدید، Marshalling روی موقعیت فیلد ها حساس میشه.
فرضا در این struct من مشخص می کنم که میخوام به همون ترتیب نوشتن (اول A و بعد B) باشه :

using System.Runtime. InteropServices;

[StructLayout (LayoutKind.Sequential)]
public struct MyStruct
{
public int A;
public int B;
}


یا ممکنه صریحا مشخص کنم که اول B در Offset صفر (شروع حافظه ثبت بشه) و بعد A چهار بایت بعدش ثبت بشه :

using System.Runtime. InteropServices;

[StructLayout (LayoutKind.Explicit)]
public struct MyStruct
{
[FieldOffset(4)]
public int A;

[FieldOffset(0)]
public int B;
}


حالا مشکل کد شما اینه که DevBroadcastVolume در حالت Auto است، Marshal نمیدونه اگر بخواد با محیط Unmanaged تبادل داده کنه فیلد های داخل DevBroadcastVolume رو باید کجای حافظه پیدا کنه، ترتیب و موقعیت شون مشخص نیست. الان نمیدونه Mask چند بایت از شروع حافظه اون IntPtr فاصله داره. نمیدونه vol.Mask کجای حافظه است. برای همین نمیتونه Marshalling رو انجام بده.

حداقل کاری که می توانید بکنید اینه که جایی که اون struct ئه DevBroadcastVolume تعریف شده بروید و در سطر قبل از struct با [StructLayout (LayoutKind.Sequential)] حالت Sequential رو انتخاب کنید تا Marshal متوجه بشه که میخواهید با همون ترتیب نوشتن فیلد ها در حافظه قرار بگیرند.

سلام
خیلی ممنون استاد از توضیحات ارزنده و کامل تون .

مدیریت انجمن ، یه دکمه ی تشکر بذارن لطفا ، حداقل بتونیم از پست های مهم تشکر کنیم تا حداقل یه کم انجام وظیفه داده باشیم نسبت به کسی که زحمت جواب میکشه .

qasemf
یک شنبه 01 فروردین 1400, 15:20 عصر
در NET. یک ماشین مجازی هست و یک محیط مدیریت شده (Managed) که از محیط بیرون از NET. (محیط Unmanaged) جدا است.
اگر بخواهید داده بین این دو محیط رد و بدل کنید، داده باید به یک قالب قابل انتقال تبدیل بشه تا بشه انتقالش داد، به این تبدیل داده که برای انتقال مناسبش می کنه Marshalling میگن.

حالا بریم سراغ بحث انتقال داده اون struct مورد نظر.
وقتی یک structure در محیط NET. تعریف میشه، باید یکسری فیلد کنار هم در حافظه اش قرار بگیرند، پس باید موقعیت فیلد های داخلش در حافظه اون structure مشخص بشه.
مثلا اینکه A باید اول قرار بگیره یا B، البته بحث چینش پیچیده تر از اینه که اول A باشه یا B ولی در همین حد به موضوع مربوطه.

public struct MyStruct
{
public int A;
public int B;
}


برای مشخص کردن موقعیت این فیلد ها سه حالت وجود داره، Auto و Explicit و Sequential که ییشفرض هم Auto است.
Auto یعنی بصورت خودکار موقعیت آیتم ها در حافظه مشخص بشه، یعنی برنامه نویس اصلا برایش مهم نیست که با چه ترتیبی ثبت میشن.
Explicit یعنی خود برنامه نویس صریحا موقعیت هر فیلد رو تعیین کنه.
Sequential یعنی با همون ترتیب نوشتن کد ثبت بشن.

مادامی که از اون structure فقط در داخل محیط NET. (یعنی محیط Managed) استفاده می کنید همون حالت Auto کاملا مناسبه و در حقیقت برای کد #C شما اهمیتی نداره که کجا و چطور ذخیره میشه. ولی اگر بخواهید به محیط بیرون از NET. (یعنی محیط Unmanaged) ارتباط اش بدید، Marshalling روی موقعیت فیلد ها حساس میشه.
فرضا در این struct من مشخص می کنم که میخوام به همون ترتیب نوشتن (اول A و بعد B) باشه :

using System.Runtime. InteropServices;

[StructLayout (LayoutKind.Sequential)]
public struct MyStruct
{
public int A;
public int B;
}


یا ممکنه صریحا مشخص کنم که اول B در Offset صفر (شروع حافظه ثبت بشه) و بعد A چهار بایت بعدش ثبت بشه :

using System.Runtime. InteropServices;

[StructLayout (LayoutKind.Explicit)]
public struct MyStruct
{
[FieldOffset(4)]
public int A;

[FieldOffset(0)]
public int B;
}


حالا مشکل کد شما اینه که DevBroadcastVolume در حالت Auto است، Marshal نمیدونه اگر بخواد با محیط Unmanaged تبادل داده کنه فیلد های داخل DevBroadcastVolume رو باید کجای حافظه پیدا کنه، ترتیب و موقعیت شون مشخص نیست. الان نمیدونه Mask چند بایت از شروع حافظه اون IntPtr فاصله داره. نمیدونه vol.Mask کجای حافظه است. برای همین نمیتونه Marshalling رو انجام بده.

حداقل کاری که می توانید بکنید اینه که جایی که اون struct ئه DevBroadcastVolume تعریف شده بروید و در سطر قبل از struct با [StructLayout (LayoutKind.Sequential)] حالت Sequential رو انتخاب کنید تا Marshal متوجه بشه که میخواهید با همون ترتیب نوشتن فیلد ها در حافظه قرار بگیرند.


ممنونم از توضیحات دقیقتون فقط الان یه خطای دیگه داره میده 153171 که من خیلی تو اینترنت گشتم ولی متوجه نشدم دلیلش چیه!! البته داره میگه نمیتونه اطلاعات رو بخونه و دسترسی نداره

the king
یک شنبه 01 فروردین 1400, 16:20 عصر
ممنونم از توضیحات دقیقتون فقط الان یه خطای دیگه داره میده 153171 که من خیلی تو اینترنت گشتم ولی متوجه نشدم دلیلش چیه!! البته داره میگه نمیتونه اطلاعات رو بخونه و دسترسی نداره
متاسفانه درست پیوست نشده و چیزی نمیتونم ببینم.

qasemf
یک شنبه 01 فروردین 1400, 23:19 عصر
متاسفانه درست پیوست نشده و چیزی نمیتونم ببینم.
153172
این خطا رو میده

the king
دوشنبه 02 فروردین 1400, 02:53 صبح
153172
این خطا رو میده
این DevBroadcastVolume تون چرا اینطوریه؟ ساختاری که یک Mask ئه string داشته باشه نداره.
تعریف ساختارش (تعاریف API در مستندات مایکروسافت به زبان ++C ئه) اینجا هست :
https://docs.microsoft.com/en-us/windows/win32/api/dbt/ns-dbt-dev_broadcast_volume

این نمونه کد پیوستی رو ببینید.
153173

qasemf
دوشنبه 02 فروردین 1400, 15:24 عصر
این DevBroadcastVolume تون چرا اینطوریه؟ ساختاری که یک Mask ئه string داشته باشه نداره.
تعریف ساختارش (تعاریف API در مستندات مایکروسافت به زبان ++C ئه) اینجا هست :
https://docs.microsoft.com/en-us/windows/win32/api/dbt/ns-dbt-dev_broadcast_volume

این نمونه کد پیوستی رو ببینید.
153173

خیلی خیلی ممنونم مثل همیشه متشکرم از این همه لطف و محبتی که نسب به امثال بنده دارید