PDA

View Full Version : نوشتن dll در دلفی و استفاده در VB6



N30TheM4TRIX
شنبه 03 تیر 1391, 21:12 عصر
سلام و خسته نباشیدبه همه
من یه برنامه نوشتم (در vb) که باید پردازش هایی که بیش از مثلاً 5 درصد از cpu رو استفاده می کنن ببنده

این کد رو در دلفی نوشتم و به dll تبدیل کردم اما نوع داده ها در این دو زبان یکی نیست چکار کنم
راهنمایی کنید.
کد dll
library Project1;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses
SysUtils,
Classes,
madKernel,
Windows;

{$R *.res}
{
(c) Janis Elsts, http://w-shadow.com/
Last Updated : 27.08.2006

uCpuUsage.pas provides some functions that let you
get the CPU usage (in percent) of a given process. Note that
the usage is calculated for a *period of time* elapsed since
last wsCreateUsageCounter or wsGetCpuUsage call for that process.
This unit is freeware, feel free to use/modify in any way you like.

Using this unit :

cnt : PCPUUsageData;
....
//Initialize the counter
cnt:=wsCreateUsageCounter(Process_id);
//Allow for some time to elapse
Sleep(500);
//Get the CPU usage
usage:=wsGetCpuUsage(cnt);
//The returned value is a real number between 0 and 100 (representint %).
//Destroy the counter and free memory
wsDestroyUsageCounter(cnt);
}
const
wsMinMeasurementInterval=250; {minimum amount of time that must
have elapsed to calculate CPU usage, miliseconds. If time elapsed
is less than this, previous result is returned, or zero, if there
is no previous result.}

type
TCPUUsageData=record
PID,Handle:cardinal;
oldUser,oldKernel:Int64;
LastUpdateTime:cardinal;
LastUsage:single; //Last result of wsGetCpuUsage is saved here
Tag:cardinal; //Use it for anythin you like, not modified by this unit
end;
PCPUUsageData=^TCPUUsageData;



function wsCreateUsageCounter(PID:cardinal):PCPUUsageData;
var
p:PCPUUsageData;
mCreationTime,mExitTime,mKernelTime,
mUserTime:_FILETIME;
h:cardinal;
begin
result:=nil;
//We need a handle with PROCESS_QUERY_INFORMATION privileges
h:=OpenProcess(PROCESS_QUERY_INFORMATION,false,PID );
if h=0 then exit;
new(p);
p.PID:=PID;
p.Handle:=h;
p.LastUpdateTime:=GetTickCount;
p.LastUsage:=0;
if GetProcessTimes(p.Handle,mCreationTime,mExitTime,m KernelTime,
mUserTime) then begin
//convert _FILETIME to Int64
p.oldKernel:=int64(mKernelTime.dwLowDateTime or
(mKernelTime.dwHighDateTime shr 32));
p.oldUser:=int64(mUserTime.dwLowDateTime or
(mUserTime.dwHighDateTime shr 32));
Result:=p;
end else begin
dispose(p);
end;
end;

procedure wsDestroyUsageCounter(aCounter:PCPUUsageData);
begin
CloseHandle(aCounter.Handle);
dispose(aCounter);
end;

function wsGetCpuUsage(aCounter:PCPUUsageData):single;
var
mCreationTime,mExitTime,mKernelTime,
mUserTime:_FILETIME;
DeltaMs,ThisTime:cardinal;
mKernel,mUser,mDelta:int64;
begin
result:=aCounter.LastUsage;

ThisTime:=GetTickCount;
//Get the time elapsed since last query
DeltaMs:=ThisTime-aCounter.LastUpdateTime;
if DeltaMs<wsMinMeasurementInterval then exit;
aCounter.LastUpdateTime:=ThisTime;

GetProcessTimes(aCounter.Handle,mCreationTime,mExi tTime,mKernelTime,
mUserTime);

//convert _FILETIME to Int64
mKernel:=int64(mKernelTime.dwLowDateTime or
(mKernelTime.dwHighDateTime shr 32));
mUser:=int64(mUserTime.dwLowDateTime or
(mUserTime.dwHighDateTime shr 32));

//get the delta
mDelta:=mUser+mKernel-aCounter.oldUser-aCounter.oldKernel;
aCounter.oldUser:=mUser;
aCounter.oldKernel:=mKernel;
Assert(DeltaMs>0);
Result:=(mDelta/DeltaMs)/100; //mDelta is in units of 100 nanoseconds, so...
aCounter.LastUsage:=Result; //just in case you want to use it later, too
end;

exports

wsCreateUsageCounter ,
wsGetCpuUsage ,
wsDestroyUsageCounter;
begin
end.

بهروز عباسی
یک شنبه 04 تیر 1391, 15:47 عصر
این کد رو در دلفی نوشتم و به dll تبدیل کردم اما نوع داده ها در این دو زبان یکی نیست چکار کنم
اگه ممکنه کمی بیشتر توضیح بده
اگر منظورت اینه که در دلفی cardinal داریم و معادلش در vb چیه؟من نمیدونم:لبخند:
اما د رکتاب مرجع توابع API 32Bit تالیف حسین صادقی راد
آمده که:معادل Integer دلفی در ویژوال بیسیک long و
معادل Pchar دلفی در ویژوال بیسیک String می باشد همین.

N30TheM4TRIX
یک شنبه 04 تیر 1391, 16:10 عصر
آقای عباسی ممنون

اما کسی برای cardinal و... معادلی نداره؟

بهروز عباسی
یک شنبه 04 تیر 1391, 16:16 عصر
آقای عباسی ممنون
خواهش می کنم
اما فکر نمی کنی اگه توی تالار vb مطلب مورد نظرت رو دنبال می کردی بهتر بود؟
چون اینطوری باید در دلفی کد بنویسی با هزار دردسر در Vb استفاده کنی و...

موفق باشی

BORHAN TEC
یک شنبه 04 تیر 1391, 17:45 عصر
نوع داده ای Cardinal در VB6 هیچ معادلی ندارد.

Felony
یک شنبه 04 تیر 1391, 18:36 عصر
تو اون کد نیازی به تعریف داده های Cardinal نیست ، شما تو VB به جای Cardinal از Long استفاده کن .

AbbasVB
چهارشنبه 15 آذر 1391, 16:31 عصر
سلام

معادل Pchar دلفی در ویژوال بیسیک String می باشد همین.
من این کارو کردم اما رشته ای که قراره در Vb نمایش داده بشه کلاً بهم ریخت است انگار کدش کردن
من بجای pchar که به یونیکد اشاره می کنه (در نسخه های جدید) از Pansichar که معادل pchar گفته شده در کتاب مذکور هستش استفاده کردم اما مشکل همچنان به قوت خود باقی است.

لطفاً راهنمایی کنید

Ananas
چهارشنبه 15 آذر 1391, 16:56 عصر
یعنی تو vb هیچ عدد 32 بیتی ای ندارید؟ اشاره گر چی؟ DWORD ندارید؟

من بجای pchar که به یونیکد اشاره می کنه (در نسخه های جدید) از Pansichar که معادل pchar گفته شده در کتاب مذکور هستش استفاده کردم اما مشکل همچنان به قوت خود باقی است.
شرمنده درست نفهمیدم چی گفتی ولی ظاهرا مربوط به سایز کاراکتر ها هست مثلا اگه تو دلفی 16 بیت باشن و تو vb سایزشون 8 بیت باشه باید کاراکتر ها رو در یک حلقه برای کل رشته تبدیل کنید.

AbbasVB
چهارشنبه 15 آذر 1391, 17:26 عصر
یعنی تو vb هیچ عدد 32 بیتی ای ندارید؟ اشاره گر چی؟ DWORD ندارید؟

شرمنده درست نفهمیدم چی گفتی ولی ظاهرا مربوط به سایز کاراکتر ها هست مثلا اگه تو دلفی 16 بیت باشن و تو vb سایزشون 8 بیت باشه باید کاراکتر ها رو در یک حلقه برای کل رشته تبدیل کنید.
عدد 32 رو نمی دونم
اما دوتای بعدی رو نداریم
منظورم این بود که اگه تابعی که در dll ایجاد شده در دلفی وجود داره یک رشته (مثلاً : "AAA" ) رو برگردونه چیزی که در vb نمایش داده میشه یک رشته عجیب و غریب و غیر قابل فهمه که هر بار هم تغییر میکنه.

Ananas
چهارشنبه 15 آذر 1391, 23:04 عصر
که هر بار هم تغییر میکنه.
احسنت به نکته ی مهمی اشاره کردی، آدرس رشته رو اشتباه می فرستی و میگیری.

عدد 32 رو نمی دونم
اگه vb نوع 32 بیتی بدون علامت نداشته باشه کلا بیخیالش شو چون اسکریپت 3DsMax هم عدد 32 بیتی که هیچ عدد 64 بیتی داره. بگرد پیدا میکنی. cardinal نوع 32 بیتی بدون علامت هست. همون long که آقا ماهان گفت رو امتحان کن احتمالا همونه.

اما دوتای بعدی رو نداریم
DWORD تو برنامه نویسی ویندوزه.
http://www.powerbasic.com/support/help/pbwin/html/Double-word_%28___%29.htm
و
http://www.powerbasic.com/support/help/pbwin/html/DEFBYT_DEFCUR_DEFCUX_DEFDBL_DEFDWD_DEFEXT_DEFINT_D EFLNG.htm
آدرس های بالا یه چیزایی از DEFDWD گفته. من هالیم نمیشه چی میگه ببین همچین چیزی نمی تونی استفاده کنی.

Delphi Coder
پنج شنبه 16 آذر 1391, 03:14 صبح
ببینید ایــــــــن کـــــــد (http://www.bigresource.com/VB-GetProcessTimes-CPU-process-usage-percent--xJhyaXMtQI.html) VB به کارتون میاد؟
کلا من فکر میکنم این کار رو تو خود VB انجام بدید راحتتر و بهتر باشه.

AbbasVB
پنج شنبه 17 مرداد 1392, 20:28 عصر
درود دوستان
مجبور بودم این تاپیک رو دوباره بالا بکشم
من مجبورم از یکسری کد های دلفی استفاده کنم که شاید نمونه اش با وی وی گیر نیاد یا تبدیلش غیر ممکن باشه
برای همین باید اون کد ها رو به Dll تبدیل کنم و توی وی بی 6 استفاده کنم
ولی وی بی با داده های رشته ای دلفی ناسازگاره
از دی ال ال های دلفی توی بقیه زبان های جدید تر می شه استفاده کرد و مشکل نداره ولی با وی بی که قدیمیه مشکل داره حداقل توی کار با رشته ها
برای حل این مشکل کسی راهکاری به نظرش نم رسه هر چی توی نت گشتم چیزی نبود
خیلی برام حیاتیه اگه کسی می تونه کمک کنه

یوسف زالی
پنج شنبه 17 مرداد 1392, 22:55 عصر
بهترین کار استفاده از انواع پیشنهادی ویندوزی هست.
مثلا DWORD و این چیزا.
برای رشته هم باید PChar بگیرید. همون رشته است ولی با نال ختم می شه.

AbbasVB
پنج شنبه 24 مرداد 1392, 22:49 عصر
سلام
این که کسی پاسخ درست و حسابی نداد بماند
برای حل این مشکل یه راه حل نه چندان اصولی پیدا کردم و اونم استفاده از تابع سند مسیج است
به این صورت که برای ارسال متن به DLL مت را داخل تک تکست باکس می ریزیم سپس هندل فایل تکست را به Dll ارسال می کنیم و Dll خودش متن را می خواند
و برای دریافت متن هندل تکست باکس را به Dll می دهیم و Dll متن را داخل تکست باکس می ریزد
این کار شاید دور قمری زدن باشد ولی چاره پیدا نکردم
مشکل این جاست که Dll رشته رو می گیره ولی هندل تکست باکس رو نمی گیره(وقتی از وی بی بهش ارسال می کنم)
با تشکر