الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

اريد استخدام نفس ملف ال Dll مع برنامج سي وبرنامج سي شارب في نفس الوقت ؟؟

بدأه LibyanITGirl في 24 ديسمبر 2009 · 22 رد · 1,591 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته

لقد قمت بإنشاء ملف dll وقمت باستدعاءه في برنامج مكتوب بلغة السي مرة وفي برنامج سي شارب مرة اخرى (منفصلات)

أريد ان استخدمه ، استدعيه في نفس الوقت في كلا البرنامجين

السبب : أريد أن أقوم بتمرير حرف char من برنامج السي إلى برنامج السي شارب

هذاهو الكود :

Mydll.h



#ifndef __DLL_H_
#define __DLL_H_
#include <windows.h>

#define DLL_EXPORT __declspec(dllexport)

#define EXPORT __declspec(dllexport)

#ifdef __cplusplus
extern "C"
{
#endif

char DLL_EXPORT get(void);

void EXPORT set(char f);

#ifdef __cplusplus
}
#endif

#endif

Mydll.cpp



#include "Mydll.h"

extern "C" static char o;

void EXPORT set(char f){
o = f ;
}


char DLL_EXPORT get(void){
return o;
}


BOOL WINAPI DllMain(HANDLE hModule,DWORD dwReason,LPVOID lpReserved){
return TRUE;
}

C Code :



#include<stdio.h>
#include<windows.h>

main(){

HANDLE ldll;

typedef void (*set)(char f);

char k = 's' ;

set Set;

ldll = LoadLibrary(TEXT("Mydll.dll"));

Set = (set)GetProcAddress(ldll, "set");

Set(k);

}

C# Code :


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace Csharp
{
class Program
{

[DllImport("Mydll.dll")]
public static extern char get();

static void Main(string[] args)
{

Console.WriteLine(get());
Console.Read();

}
}
}


lilgirllaptopsoftened2c.jpg

#2

اين المشكله ؟؟

مدونتي: C++ Tips and Tricks

#3

المشكلة انني لا أجد النتيجة التي اريدها !!

المفروض عندما اقوم بتنفيذ البرامج أحصل على char في C# console

ولكن ال console تظهر فارغة !!

ما السبب ؟؟

lilgirllaptopsoftened2c.jpg

#5

انت لا تجد نتيجه لأنك تستدعى get دون ان تقوم بوضع قيمه بإستخدام set، امر اخر و هو ان النوع char داخل الـ C/C++ يحجز مساحة 1 بايت و مدى الأرقام له -127/128فى حين ان النوع char داخل الدوت نت يحجز مساحة 2 بايت و مدى الأرقام له هو 0/65535 لذا و كما ترى لابد من عمل marshaling لهذه الدوال داخل الدوت نت لتعمل جيدا.

هذه هى النسخه الخاصه بى بعد التعديلات و قمت بتجربتها على السى شارب و عملت

MyDll.h

#ifndef MYDLL_H
#define MYDLL_H

#define EXPORT __declspec(dllexport)

extern "C" void EXPORT __stdcall set(char c);
extern "C" char EXPORT __stdcall get(void);

#endif

MyDll.cpp

#include "MyDLL.h"
#include <windows.h>

extern "C" static char o = ' ';

void __stdcall set(char c)
{ o = c; }

char __stdcall get(void)
{ return o; }

BOOL WINAPI DllMain(HANDLE hModule,DWORD dwReason,LPVOID lpReserved)
{ return TRUE; }

exports.def

LIBRARY	"MyDll"
EXPORTS
	set @1
	get @2

و داخل السى شارب

test.cs

using System;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("tst.dll")]
    [return: MarshalAs(UnmanagedType.I1)]
    public static extern char get();

    [DllImport("tst.dll")]
    public static extern void set([MarshalAs(UnmanagedType.I1)]char value);


    static void Main(string[] args)
    {
        char i = get();
        Console.WriteLine("initial value is: '{0}', Ascii Code: {1}", i, (int)i);
        Console.WriteLine("changing value to 'm'");
        set('m');
        Console.WriteLine("value changed to '{0}'",get());
    }
}

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#6

حسنا ، قمت بالتغييرات الي قمت بها

لكن مازلت لا أحصل على نتيجة

ما هي التغييرات التي اقوم بها على برنامج السي ؟

lilgirllaptopsoftened2c.jpg

#7
اقتباس
لكن مازلت لا أحصل على نتيجة

داخل السى شارب ام السى ؟؟

ارجو ارفاق نسخة البرنامج التى تعمل عليها، ان استطعت.

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 24 ديسمبر 2009 في 15:59

مدونتي: C++ Tips and Tricks

#8

لا أرى النتيجة في السي شارب

أنا أقوم بإرسال char من برنامج السي إلى برنامج السي شارب .

كود برنامج السي مكتوب فوق لم أقم بتغيير أي شي.

قمت بتغيير ما قمت أنت بتغييره.

جربت ان أرسل وأستقبل من السي شارب كما فعلت انت وتم بنجاح وظهرت لي النتيجة .

ولكن عندما حاولت ان ارسل من السي لم يعمل .

lilgirllaptopsoftened2c.jpg

#9

انا اعرف لماذا لم يعمل، السبب انك قمت داخل برنامج السى بتعريف مؤشرات الدالتين بهذا الشكل

typedef void (*set)(char f);
typedef char (*get)(void);

هذا التعريف غير مطابق للتعريف الذى قمنا بعمله داخل النسخه المعدله و الذى يأخذ الشكل التالى

void __stdcall set(char c);
char __stdcall get(void);

الإختلاف كما ترى فى الـ calling convention حيث انك تستخدم __cdecl (الإفتراضى) و انا استخدم __stdcall لذا ليعمل المثال معك فقط قم بتعديل صيغة مؤشرات الدوال لتصبح كالتالى:

typedef void (__stdcall *set)(char f);
typedef char (__stdcall *get)(void);

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#10

إرسال من سي ل سي ينجح وأرى الحرف

من سي شارب لسي شارب أحصل على النتيجة أيضا

ولكن من سي ل سي شارب لا أرى نتيجة :blink: :unsure: :mellow:

lilgirllaptopsoftened2c.jpg

#11

تم عمل المكتبه بالـ C++ و بعد ذلك تم عمل marshaling لها داخل السى شارب و عملت و ايضا تم استخدامها من داخل السى و عملت، اين المشكله ؟؟ :huh:

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 25 ديسمبر 2009 في 01:58

مدونتي: C++ Tips and Tricks

#12

أقصد بعدما غيرت تعريف مؤشرات الدالة داخل السي طبعا

lilgirllaptopsoftened2c.jpg

#13

هل تصنع لى معروف و تقوم بعمل مشروع صغير تضع فيه الأكواد النهائيه التى تستخدمها ثم ترفقها هنا

مدونتي: C++ Tips and Tricks

#14

حسنا

lilgirllaptopsoftened2c.jpg

#15

أخي الخط عندي تعبان جدا :(

سأرفع الملف عندما يصبح الخط أسرع

lilgirllaptopsoftened2c.jpg

#17

لقد قمت برفع الملف

My project.rar

lilgirllaptopsoftened2c.jpg

#18

اخى قمت بتجربة المشروع و لم يعمل معى لا فى csharp و لا c و لا حتى c++ و السبب فى ذلك ان LoadLibrary تعود بـ NULL و بالتبعيه GetProcessAddress تعود بـ NULL يبدو ان Dll المرفقه بها مشكله لذا قمت بعمل solution و وضعت به الـ 3 مشاريع و غيرت مكان الـ output لهم لفولدر واحد اسمه debug داخل فولدر الـ solution مباشرة كل ما عليك هو ان تحدد الـ active project و ستجد النتيجه.

قمت بتجربة الأمثله كلها و عملت مع النسخه الموجوده بالمرفقات.

CompositeSolution.rar

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#19

كنت أظن أنك تريد الكود فقط وليش المشاريع ، أنا أستخدم VS 2005

كل شيء عندي يعمل مثلما يعمل مشروعك

أخي يبدوا انني لم أعرف كيف أوصل سؤالي :mellow:

ما أريده أنني عندما أعمل compile لل C فإن الحرف المخزن يذهب لل dll ومنه إلى C# كسلسلة واحدة

كيف أقوم بذلك ؟

لدي شعور أن المشكلة في طريقة ال compile

ربما هنا إعدادات أو طريقة معينة للتطبيق ؟؟؟؟

lilgirllaptopsoftened2c.jpg

#20
اقتباس
أخي يبدوا انني لم أعرف كيف أوصل سؤالي

نعم هذا صحيح :unsure:

اقتباس
ما أريده أنني عندما أعمل compile لل C فإن الحرف المخزن يذهب لل dll ومنه إلى C# كسلسلة واحدة

لازلت لا افهم :wacko:، كيف تريد ارسال حرف كسلسله واحده. ؟؟؟؟؟؟

مدونتي: C++ Tips and Tricks

#21

لالالالالا لا أقصد إرسال الحرف كسلسلة واحدة

أقصد أنني اريد إرساله في مسار من السي إلى ال dll إلى C# مجرد تعبير مجازي

:wacko:

أنا أقوم با cmpile السي ثم compile السي شارب ، هل هذا صحيح ؟

أم هناك شي أنا أغفله ؟

lilgirllaptopsoftened2c.jpg

#22
اقتباس
أقصد أنني اريد إرساله في مسار من السي إلى ال dll إلى C# مجرد تعبير مجازي

اخى السؤال لم يتضح، ماذا تقصد بــ "فى مسار".

سأعطيك مثال عسى ان يقرب الصوره بييننا، دوال الـ Win32API نقوم بالتصريح عنها داخل برنامج الـ C# و بعد ذلك نقوم بتمرير قيم لها و عند تنفيذ البرنامج يتم تمرير القيم السابق ذكرها للداله الفعليه الموجوده فى المكتبه xxx ليتم تنفيذها ثم الرجوع بالقيمه النهائيه لنا داخل السى شارب.

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

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#23

أخي محمد أظن الأخت تقصد عمل IPC .

ابحثي عن استخدام الـPipes او اي طرق الـIPC الاخرى مثل الـShared Memory عن طريق الـFile Mapping مثلا .

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…