Wywoływanie metod z niezarządzanych DLL.

0

Witam,
Mam następujący problem. Chciałbym z poziomu C# wywołać niezarządzane metody z zewnętrznej dll do połączenia z bazą danych postgres ( konkretnie libpq.dll - z niezależnych ode mnie przyczyn jestem zmuszony korzystać właśnie z tej DLL).

Znalazłem dużo materiałów w sieci odnośnie wywoływania metod z importowanych, niezarządzanych DLL m .in. ( http://msdn.microsoft.com/en-us/magazine/cc301501.aspx ) ale nie opisano tu jak postępować w sytuacji w której metoda zwraca obiekt typu ( w przytoczonym artykule metody importowane zwracają struktury) którego definicja jest również zawarta w DLL ( w tym wypadku - chcąc nawiązać połączenie wywołuję metodę PQconnectdb i otrzymuję w odpowiedzi obiekt typu PGconn). Jak sobie poradzić w tej sytuacji?

0

Musisz zrobić taki sam obiekt w c#, patrz dokumentacja: http://www.digipedia.pl/pgsql/6.3/c4402.htm

To tak na szybko co wymysłiłem, w pracy siedze.

0

Trzeba przepisać strukturę na C#, koniecznie z LayoutKind.Sequential:

[StructLayout(LayoutKind.Sequential)]
struct Foo
{
  public int x;
  public int y;
  // itd reszta pól

  // można dodać konstruktor
  public Foo(int ax, int ay)
  {
      x = ax;
      y = ay;
  }
}

PS. z tego co widzę z opisu postgresa, to funkcja zwraca wskaźnik na strukturę (to istotna różnica), poza tym pola tej struktury (chyba) nie są do niczego tobie potrzebne?

Jeżeli tak jest, to zdeklaruj że funkcja zwraca po prostu IntPtr (czyli wskaźnik) i tyle.

0

@Azarien być może nie wyraziłem sie precyzyjnie, ale chodziło mi o to że potrafię sobie poradzić ze strukturą dzięki artykułowi który podlinkowałem, natomiast nie wiem jak sobie poradzić z obiektem klasy której definicja jest też zaszyta w importowanej dll ;-) Pola obiektu zwracanego przez funkcję tu akurat nie są potrzebne, ale zaraz będę chciał wysyłać zapytania i odbierać wyniki, wówczas już niestety nie mogę użyć IntPtr.

@szulak Też kombinowałem w ten sposób tylko nie wiem jak zadeklarować poszczególne metody tej klasy? Wirtualne, abstrakcyjne, zwykłe? I co jeżeli znajdzie się metoda która będzie zwracać lub przyjmować obiekt innej klasy - po raz kolejny trzeba będzie go przepisać na kod zarządzany?

0

To może pomóć: http://blogs.msdn.com/b/jonathanswift/archive/2006/10/02/780637.aspx
Jak będę w domu to spróbuję takie coś napisać.

0

Pola obiektu zwracanego przez funkcję tu akurat nie są potrzebne, ale zaraz będę chciał wysyłać zapytania i odbierać wyniki, wówczas już niestety nie mogę użyć IntPtr.

Jak to nie? PGconn jest zawsze przekazywane jako wskaźnik PGconn*, więc możesz przekazywać po prostu IntPtr.
Skoro pola struktury nie są ci potrzebne, to nie są ci potrzebne.

tylko nie wiem jak zadeklarować poszczególne metody tej klasy? Wirtualne, abstrakcyjne, zwykłe?

Jakie metody? Pokaż jakiś przykład klasy i metody.

0

Zostawiając już PGConn - faktycznie mogę dostać się do pól struktury którą zwróci mi niezarządzana metoda w taki sposób jak podaliście. Co natomiast w sytuacji, kiedy mamy do czynienia z klasą C++, a nie strukturą. Pytam o sytację w której przykładowo klasa w C++ wygląda tak:

class Rectangle {
    int x, y;
    JakiśTyp JakiśMember
  public:
       int area () {return (x*y);
       JakiśTyp GetJakiśMember() {return JakiśMember}

};

Jak w takiej sytuacji wyglądałoby przepisywanie obiektu pod c#?

0

Spójrz na post Azarien'a, i analogicznie zrób nową klase.

0

C# nie obsługuje klas (z metodami) C++.

Możesz:
• użyć DLL-ki, która eksportuje funkcje C (globalne) a nie klasy C++. Niektóre biblioteki mają interfejs API dla C i osobny dla C++. Użyj tego z C.
• Napisać w C++/CLI klasę pomostową, która jest widoczna pod C# a jednocześnie ma dostęp do natywnych klas i funkcji C++.

1 użytkowników online, w tym zalogowanych: 0, gości: 1