2009-03-02 25 views
4

'dan edinme Bazı yetkili ANSI standart C kodları var. Bunun anlamı, kaynağa sahip olmama rağmen, bu eylemlerin otoriteyi geçersiz kılacağı için, başka bir dile tercüme edemem veya arama argümanlarını değiştiremem. 150'den fazla fonksiyon var.Yönetilmeyen C++ işlevlerinden C#

Dosya adlarını .C ile .CPP arasında değiştirmek gibi, yaptığım Visual Studio 2009'un C++ derleyicisini kullanarak derleme yapabilmem için bazı değişiklikler yapabilirim. Derleyici yönergeleri ve benzerleri de eklenebilir. Gerekirse bir sarma tabakasından da geçebilirim.

başka kısıtlama benim şirket değilbana herhangi bir C# kodu güvensiz anahtar kelimeyi kullanmak istiyorum yapmasıdır.

Bu işlevlere bir C# programından erişmem gerekiyor.

Tipik C/C++ işlev aşağıdaki gibidir: dizi içeriği bazen girişi, bazen çıkış ve nadiren her ikisi de
double SomeFunction(double a, double[3] vec, double[3][3] mat);
.

İlk önce yönetilmeyen bir DLL (Extern C işaretli işlevlerle) yapmayı denedim. Sadece basit argümanlarla (int, double) fonksiyonlar iyi çalıştı, ama Marshal dizilerini nasıl belirleyemedim. (Aslında, bazı örnek kodlar buldum, ancak 150 kez çoğaltmak son derece karmaşık ve mantıksızdı.)

Daha sonra aynı çözüm içinde C++ ve diğeri C# içinde iki proje denedim. C++ projesinde, yalnızca yönetilmeyen olarak işaretlenmiş orijinal işlevi denen yönetilen bir işlev oluşturdum. Bu son derece temiz ve basitti ve yine basit argümanlar iyi çalıştı. Ancak, diziler için argüman türlerinin C# ile C++ sınırı arasında nasıl eşleştirileceğini bulamadım. (Ve yukarıda belirtildiği gibi, işaretçi almak için güvensiz kullanamıyorum).

Kesinlikle yapmaya çalıştığım şey mümkün olmalıdır.
Bu işlevlere ulaşmanın en iyi yolu nedir?
(yukarıdaki işlevini kullanarak Örnek kod gerçekten harika olurdu.)

cevap

4

Numune C/C++ uygulaması:

extern "C" __declspec(dllexport) 
double SomeFunction(double a, double vec[3], double mat[3][3]) { 
    double sum = a; 
    for (int ix = 0; ix < 3; ++ix) { 
    sum += vec[ix]; 
    for (int iy = 0; iy < 3; ++iy) { 
     sum += mat[ix][iy]; 
    } 
    } 
    return sum; 
} 

Numune C# kullanımı:

private void Form1_Load(object sender, EventArgs e) { 
    double[] vec = new double[3]; 
    double[,] mat = new double[3, 3]; 
    for (int ix = 0; ix < 3; ++ix) { 
    vec[ix] = ix; 
    for (int iy = 0; iy < 3; ++iy) { 
     mat[ix, iy] = (ix + 1) * iy; 
    } 
    } 
    double sum = SomeFunction(1, vec, mat); 
} 
[System.Runtime.InteropServices.DllImport("cpptemp8.dll")] 
private static extern double SomeFunction(double a, double[] vec, double[,] mat); 
+0

Ah için Pınvoke üretecektir, teşekkür ederim! Bu sorunun anahtarı, C++ 'da dizinin çift [] [] olarak, ancak C# olarak çift [,] olarak bildirildi. İlk yasal C# sözdizimi olmasına rağmen, aynı iç kuruluşu temsil etmez. Bu içgörü parçası olmadan, işe yaramazdı. –

1

çalışmak için extern ve P/ınvoke çözümünü alamıyorsanız, bir sarıcı muhtemelen en iyi bahistir. Hem yönetilen hem de yönetilmeyen kod kullanan bir yönetilen C++ DLL oluşturun. C DLL'nizdeki işlevler üzerinde yalnızca ince bir sarıcı olan bu DLL'ye bir .NET sınıfı ekleyin. C# kodunuz C++ .NET sınıfını arayabilir ve bu da C işlevlerinde ilerler.

Bu şekilde, çalışma zamanını sizin yerinize yapmak yerine, .NET ve yönetilmeyen kodlar arasında çeviri yazabilirsiniz.