PDA

View Full Version : آموزش: ارسال توابع سی شارپ ه به سی++ و صدا زدن انها



UfnCod3r
دوشنبه 18 شهریور 1392, 10:24 صبح
فرض کنید می خواهید ی سری کد ها رو در سی++ بنویسید (حالا به خاطر سرعت یا هرچی) و بعد اون توابع رو
در سی شارپ صدا بزنید .خب این کار نسبتا اسونه . کد ها رو می نویسم و به صورت dll کامپایل می کنیم .
حالا این وسط شاید لازم باشه شما به یک سری از توابع سی شارپ در سی++ دسترسی داشته باشید.
مثلا در صورت بروز خطا یه متنی ر وچاپ کنید یا ..
:شیطان::شیطان::شیطان:

اصولش اینه که ما باید ادرس اون تابع در حافظه و Calling Convention (http://en.wikipedia.org/wiki/X86_calling_conventions) تابع رو بدونیم.
Calling Convention مشخص می کنه که ترتیب پارامتر های تابع به چه صورت باشه . کدوما تو ثبات برن کدوما نرن و ..
کاری به توابع عضو کلاس نداریم توابع استاتیک در سی# _stdcall هستن.
پس این میشه کدهای قسمت سی++ .

#include <iostream>
#include <Windows.h>

#define APIDECL extern "C" __declspec(dllexport)
#define APICALL __stdcall

typedef void (__stdcall *Proc_PrintCStr)(char*);


Proc_PrintCStr gPrintCStr = nullptr;


APIDECL void APICALL RegisterDLL(Proc_PrintCStr printStr)
{
gPrintCStr = printStr;
}


APIDECL void APICALL FuncTest()
{
gPrintCStr("Hello C#‎‎‎. ;)");


چیز خاصی نداره . :لبخند:
با تابع RegisterDLL ما یه اشاره گر به تابع سی شارپی ای که می خوایم رو می گیریم
و بعد ذخیرش می کنیم تا هر وقت خواستیم صداش کنیم.:شیطان:

اینم قسمت سی# برنامه

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

namespace ConsoleApplication1
{
class Program
{
public delegate void DPrintStr(string s);

[DllImport("Test123.dll",CallingConvention = CallingConvention.StdCall)]
static extern void RegisterDLL(DPrintStr func);

[DllImport("Test123.dll", CallingConvention = CallingConvention.StdCall)]
static extern void FuncTest();


static void Main(string[] args)
{
RegisterDLL(new DPrintStr(Console.WriteLine));

FuncTest();
Console.Read();
}
}
}


تو سی شارپ ما شاره گر مثل سی++ نداریم باید ی Delegate تعریف کنیم .
delegate در واقع ادرس تابع رو نگه داشته و وقتی ما اون رو می فرستیم به تابع RegisterDLL
انگار که ادرسشو فرستادیم . :متفکر:
تمام .

مصطفی ساتکی
دوشنبه 18 شهریور 1392, 21:17 عصر
حالا این وسط شاید لازم باشه شما به یک سری از توابع سی شارپ در سی++ دسترسی داشته باشید.
مثلا در صورت بروز خطا یه متنی ر وچاپ کنید یا ..
.
می گم نکنه میخای تو C# یه انجین بنویسی بعد wrapper شو تو C++بنویسی :قهقهه:
در صورت بروز خطا همین جا اگر تو کنسول cout کنی اون طرف تو C# می بینه اگر اون هم کنسول باشه




تو سی شارپ ما شاره گر مثل سی++ نداریم باید ی Delegate تعریف کنیم .

در حالت unsafe ما تو c# اشاره گر به انواع پایه ای داریم و اشاره به تابع نداریم که جاش delegate وجود داره.
به هر حال پست جالبی بود.(چه ایرادی داره بتونیم توابعی که اونا می نویسن ما call کنیم :کف:)

FastCode
شنبه 30 شهریور 1392, 18:40 عصر
راه بهتر از این هم هست.
http://www.mono-project.com/Embedding_Mono