View Full Version : سوال: چگونگه میتوان dll ساخت که آرایه برگرداند
jblaox
چهارشنبه 19 تیر 1392, 18:36 عصر
سلام
من یک تابع دارم مثل تابع فرضی زیر ،
میخواهم مقادیر آرایه dou_arr_x و dou_arr_y و dou_arr_z و متغیر های dou_H و dou_F از تابع دریافت کنم ، مرحله بعد چگونه این تابع تبدیل به DLL کنم که در C# بتوان مقادیر دریافت کنم
من شیوه ساخت dll که یک متغییر برگردونه بلدم اما با این مشکل دارم !!
void Randum_number_Out_arr(int int_arr_counter[], int int_counter)
{
double *dou_arr_x;
dou_arr_x = new double[int_arr_counter[0]];
double *dou_arr_y;
dou_arr_y = new double[int_arr_counter[1]];
double *dou_arr_z;
dou_arr_z = new double[int_arr_counter[2]];
double dou_H,dou_F;
// set the seed
srand( (unsigned)time( NULL ) );
//---------------------
// Just only for test
for (int i = 0; i < int_counter; i++)
{
dou_arr_x[i] = rand();
dou_arr_y[i] = rand();
dou_arr_z[i] = rand();
dou_H = dou_arr_x[i] + dou_arr_y[i] + dou_arr_z[i];
dou_F = (dou_H /int_arr_counter[3]);
}
}
پیشاپیش از پاسخ های شما دوستان متشکرم
مصطفی ساتکی
چهارشنبه 19 تیر 1392, 19:07 عصر
اگر تعداد خانه حافظه از قبل مشخص هستش (استاتیک)سمت C# حافظه را اشغال کنید و اشاره گر به ابتدای آن آرایه را در signture تابع C++ استفاده کنید به صورت *double اگر در حالتی نیاز باشه که سمت برنامه C++ اختصاص حافظه نماید(دینامیک) بایستی به صورت اشاره گر به اشاره گر استفاده نماید **double.
در حالت استاتیک که ساده هستش مثال نیازی نداره ولی در حالت دینامیک به صورت زیر هستش.
void testFunc(double **arr,int *count)
{
*count = rand()%100;
double *arr_i = new double[count];
// process here
*arr = arr_i;
}
jblaox
چهارشنبه 19 تیر 1392, 20:05 عصر
اگر تعداد خانه حافظه از قبل مشخص هستش (استاتیک)سمت C# حافظه را اشغال کنید و اشاره گر به ابتدای آن آرایه را در signture تابع C++ استفاده کنید به صورت *double اگر در حالتی نیاز باشه که سمت برنامه C++ اختصاص حافظه نماید(دینامیک) بایستی به صورت اشاره گر به اشاره گر استفاده نماید **double.
در حالت استاتیک که ساده هستش مثال نیازی نداره ولی در حالت دینامیک به صورت زیر هستش.
void testFunc(double **arr,int *count)
{
*count = rand()%100;
double *arr_i = new double[count];
// process here
*arr = arr_i;
}
سلام عزیز جان ، اول تشکر کنم که لطف کردی جواب دادید .
ببخشید من رشته تحصیلیم رایانه و مشتقات ان مثل برنامه نویسی و ... نیست ! دانشجو هم نیستم ، کاسب هم نیستم برای پول هم کار نمیکنم عشقم و کارم چیز دیگر است ، اگر امکان دارد بیشتر توضیح دهید:لبخندساده:
اندازه آرایه قبل از امدن به dll در C++ کاملا مشخص و مقدار اولیه (مثلا صفر) داده شده است ، البته این بگم که ممکن اندازه تغییر کنه اما در C# هرچه قدر باشه در c++ هم همون اندازه است.
مثلا در C# اینگونه است :
double[] dou_arr_1 = new double[100];
double[] dou_arr_2 = new double[100];
double[] dou_arr_2 = new double[100];
for(int i=0; i <100; i++)
{
dou_arr_1[i]=0.0;
dou_arr_2[i]=0.0;
dou_arr_3[i]=0.0;
}
double*[] p1;
double*[] p2;
double*[] p3;
حالا با اشاره گر چه کار کنم ؟
مثلا آن تابع که اول نوشتم را در c++ چگونه بنویسم ؟؟
بعد تابع را در c++ حتما باید void تعریف کنم ؟ درسته ؟ و نیازی به __stdcall نداره ؟؟
چی پاس بدم حالا ؟؟
باز هم تشکر بابات وقت که گذاشتید .
نماز و رزه های همگی هم قبول باشه :لبخندساده:
مصطفی ساتکی
یک شنبه 23 تیر 1392, 00:28 صبح
پس آرایه شما استاتیک هستش یعنی قبل از فراخوانی سمت c# تعیین میشه که چه تعداد بایستی باشه و فضا اختصاص داده میشه بهش در هنگام فراخوانی تابع در dll اشاره گر به ابتدای خانه حافظه یا همون آدرس خانه صفر رو پاس بدید.
سمت C++ نوع function call را stdcall یا WINAPI قرار بدید و سمت c# هم به همین صورت در ضمن void به عنوان نوع خروجی تابع هستش نه function call تابع.
موفق باشید.
UfnCod3r
یک شنبه 23 تیر 1392, 09:59 صبح
__declspec(dllexport) double* GetArray(int size)
{
return new double[size];
}
//C#
[DllImport("the.dll")]
public static double[] GetArray(int size);
البته سمت سی شارپش رو درست ننوشتم . خیلی وقته سی شارپ کار نمی کنم.
ی چی تو همین مایه ها میشه :متفکر:
jblaox
یک شنبه 23 تیر 1392, 12:02 عصر
سلام
از پاسخ شما دو عزیز متشکرم ،
همونجور که شما بهتر از من میدونید پاس دادن کل متغیر ، این کار باعث میشه من هر دفعه یک کپی از ارایه را تو حافظه ایجاد کنم و با توجه به اینکه اندازه و تعداد ارایه خیلی بزرگتر از این کد پایین ترجیح میدهم با اشاره گر کار کنم ، اما هنوز موفق نشدم !
کد که جواب نمیدهد :
بخش cpp :
extern "C" __declspec(dllexport) int Random_arr(
double *bd_In_0,
int in_t)
{
// set the seed
srand( (unsigned)time( NULL ) );
for (int i = 0; i < in_t; i++)
{
bd_In_0[i] = (double)rand();
}
//--------------------------------
//Test_fun(dou_arr_x_ptr);
return 0;
}
بخش C# :
const string _dllLocationd = @"E:\Array_out_test.dll";
[DllImport(_dllLocationd)]
public static extern int Random_arr(
double* ptr,
int in_t
);
unsafe
{
fixed (double* First_arr_Pointer = &dou4[0])
{
int int_1 = Random_arr(ref First_arr_Pointer);
MessageBox.Show(dou4[0].ToString());
}
}
UfnCod3r
یک شنبه 23 تیر 1392, 12:46 عصر
این
extern "C" __declspec(dllexport) int Random_arr(
double bd_In_0[]);
در واقع یعنی
این
extern "C" __declspec(dllexport) int Random_arr(
double *bd_In_0);
سمت سی++ که تو حالت دوم درسته
سمت سی شارپ فکر کنم ادرس رو اشتباه دادی چون شما اول ادرس عنصر اول رو بدست اوردی بعد دوباره موقع فرستادن به تابع از ref استفاده کردی
درواقع شما double** فرستادی
ref رو بردار شاید درست بشه :متفکر:
jblaox
یک شنبه 23 تیر 1392, 14:15 عصر
سلام ،
من ref را هم برداشتم اما جواب نمیدهد ...
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.