Wolf216 Ответов: 2

Используйте импортированные статические функции для построения класса C++


I imported a dll file named swedll64.dll in main function of a c++ program.

#include<iostream>
#include<math.h>
#include<windows.h>

using namespace  std;

typedef double(*_swe_julday)(int, int, int, double, int);
typedef int(*_swe_calc)(double, int, int, double[], char[]);
typedef void(*_swe_revjul)(double, int, int&, int&, int&, double&);

int main()
{
HINSTANCE hInst = LoadLibrary(L"C:\\swedll64.dll");

_swe_julday swe_julday = reinterpret_cast<_swe_julday>(GetProcAddress(hInst, "swe_julday"));
_swe_calc swe_calc = reinterpret_cast<_swe_calc>(GetProcAddress(hInst, "swe_calc"));
_swe_revjul swe_revjul = reinterpret_cast<_swe_revjul>(GetProcAddress(hInst, "swe_revjul"));
return 0;
}

public class Swisseph
{
    public Swisseph()
    {
    }
    [DllImport("swedll32.dll", CharSet = CharSet.Ansi, EntryPoint = "swe_julday")]
    public extern static double xyz_swe_julday(int year, int month, int day, double hour, int gregflag);
    public static double swe_julday(int year, int month, int day, double hour)
    {
        return xyz_swe_julday(year, month, day, hour, 1);
    }

    [DllImport("swedll32.dll", CharSet = CharSet.Ansi, EntryPoint = "swe_calc_ut")]
    public extern static int xyz_swe_calc_ut(double tjd_ut, int ipl, int iflag, double[] xx, StringBuilder serr);
    public static void swe_calc_ut(double tjd_ut, int ipl, int addFlags, double[] xx)
    {
        StringBuilder serr = new StringBuilder(256);
        int ret = xyz_swe_calc_ut(tjd_ut, ipl, addFlags, xx, serr);
    }

    [DllImport("swedll32.dll", CharSet = CharSet.Ansi, EntryPoint = "swe_close")]
    public extern static void xyz_swe_close();
}


Что я уже пробовал:

 how can i build a class for imported methods?in other word where should i put this codes in class ? 
Is there another tricks to do so like Dllimport() and extern in c#(i want to do exact whatever written in  below c# code)?

2 Ответов

Рейтинг:
2

KarstenK

Вы должны построить для него класс, потому что импортированные функции являются статическими или глобальными.

Использование в C# теперь

Swisseph.xyz_swe_julday(...);
потому что ты их переименовал. Это не очень хорошая идея.

Конечно, вы должны рассмотреть возможность создания некоторого класса, который использует эти функции. Некоторое форматирование, проверка или предоставление буфера очень удобно.


Рейтинг:
1

Rick York

Вот одна из возможностей :

typedef double (*_swe_julday)( int, int, int, double, int );
typedef int    (*_swe_calc)( double, int, int, double[], char[] );
typedef void   (*_swe_revjul)( double, int, int&, int&, int&, double& );

class SWE
{
public:
    static inline _swe_julday  JulDay = nullptr;
    static inline _swe_calc    Calc   = nullptr;
    static inline _swe_revjul  RevJul = nullptr;

    static bool Initialize()
    {
        if( m_Initialized )
           return true;

        HINSTANCE hInst = LoadLibrary( _T( "swedll64.dll" ) );
        if( ! hInst )
            return false;

        JulDay = reinterpret_cast<_swe_julday>( GetProcAddress( hInst, "swe_julday" )  );
        Calc = reinterpret_cast<_swe_calc>( GetProcAddress( hInst, "swe_calc" ) );
        RevJul = reinterpret_cast<_swe_revjul>( GetProcAddress( hInst, "swe_revjul" ) );

        m_Initialized = true;
        return true;
    }

    static bool IsInitialized() const    { return m_Initialized; }

protected:
    static inline bool m_Initialized = false;
};
Это может показаться странным, потому что там есть некоторые вещи C++17, но они будут компилироваться и связываться с VS17. Я попробовал. Чтобы использовать это код будет выглядеть следующим образом:
SWE::Initialize();
SWE::JulDay( int1, int2, int3, double1, int4 );
Следует отметить, что класс со всеми статическими методами и членами-это, по сути, то же самое, что иметь эти функции и данные в пространстве имен. Даже синтаксис использования один и тот же.


Rick York

Если эта библиотека была написана на языке Си, то это решение должно быть немного скорректировано.