0

Below mentioned is my dll function in c++

static bool t72CalculateRMDMethodResult( const double     AccountBalanceAtSetup,
                                     const long       ClientCurrentAge,
                                     const char       Frequency,
                                     double *         pRMDMethodResult,
                                     IRSLookupTable & LookupTable)

Below mentioned is my c++ class which has a pointer passed as a parameter to the above function

class IRSLookupTable
{

    public:
        struct IRSLookupTableRow
        {
            unsigned int    Key;
            double          Value;
        };

        IRSLookupTable( const char * pFilename );
        IRSLookupTable( const struct IRSLookupTableRow Table[], const unsigned int NumEntries );
        virtual ~IRSLookupTable();

        bool         LookupValueByKey(const unsigned int Key, double * Value);
        virtual bool ParseLine( char * Buffer, unsigned int * Key, double * Value);
        bool         IsInitialized();

    private:
        typedef map <unsigned int, double> IRSLookupTableData;

        IRSLookupTableData m_IRSTableData;
        bool               m_bInitialized;
};

Below is how i called the the c++ dll function in c# and i am not sure it is correct or not and i am unable to enter the dll function

[DllImport("t72CalculatorDLL.dll", ExactSpelling = true, EntryPoint = "t72CalculateRMDMethodResult")]
    public static extern bool t72CalculateRMDMethodResult(double AccountBalanceAtSetup, int ClientCurrentAge, char Frequency, double* pRMDMethodResult, [MarshalAs(UnmanagedType.LPStruct)] ref IRSLookupTable LookupTable);

this the definition of the c++ class that i have written in c#

    [DataContract]
public unsafe class IRSLookupTable
{
    public struct IRSLookupTableRow
    {
        public uint Key;
        public double Value;
    };

    public IRSLookupTable()
    {
        m_bInitialized = true;
    }
    public IRSLookupTable(char* pFilename)
    {
        //        uint Key;
        //        double Value;
        //        m_bInitialized = false;

        //        Debug.Assert( pFilename );
        //        if (pFilename ==null )
        //{
        //    // return without setting the flag to true
        //    return;
        //}

        //// open the file
        //std::ifstream InputFile(pFilename);
        //if ( ! InputFile )
        //{
        //    // return without setting the flag to true
        //    return;
        //}

        //while ( InputFile.getline( &gTmpBuffer[0], BUFFERSIZE) )
        //{
        //    if ( ! ParseLine( gTmpBuffer, &Key, &Value ) )
        //    {
        //        m_IRSTableData[Key] = Value;
        //    }
        //    else
        //    {
        //        // return without setting the flag to true
        //        return;
        //    }
        //}

        //m_bInitialized = true;
    }
    public IRSLookupTable(IRSLookupTableRow* Table, uint NumEntries)
    {
        m_bInitialized = false;

        for (uint i = 0; i < NumEntries; i++)
        {
            m_IRSTableData[Table[i].Key] = Table[i].Value;
        }

        m_bInitialized = true;
    }

    ~IRSLookupTable() { }

    public bool LookupValueByKey(uint Key, double* Value) { return true; }
    public virtual bool ParseLine(char* Buffer, uint* Key, double* Value) { return true; }
    public bool IsInitialized() { return true; }


    private SortedDictionary<uint, double> m_IRSTableData;
    private bool m_bInitialized;
}

can anyone please help me with this i am totally new to c#.

vyegorov
  • 21,787
  • 7
  • 59
  • 73
krishna555
  • 223
  • 5
  • 18
  • Have u defined the IRSLookupTable type on the c# side of the code ? If so can u include its definition. – user957902 May 10 '12 at 14:51
  • yes i did and i provided the definition in the above question – krishna555 May 10 '12 at 14:55
  • What does sizeof() of an IRSLookupTable object instance return on the C++ side of the definition ? – user957902 May 10 '12 at 15:26
  • it gives me size for the object as 4 – krishna555 May 10 '12 at 15:50
  • You want to pass a C# object to existing C++ code, and have the C++ call its methods. The easy way is to change the C++ code to support a COM interface, then use the built-in COM support to implement that interface in C#. Maybe a shim over the existing C++ will do it. – Ben May 10 '12 at 16:43
  • Ya that should work ben and thanks for that idea, but i am not supposed to change the c++ code as it is an already built application and i need to just take those dlls for testing with out changing the c++ code, that is why i am wondering how to do this. – krishna555 May 10 '12 at 16:51
  • @krishna555 - If you can't change the C++ code you'll have to write some sort of wrapper since only other C++ code can call this function. You can create a native C++ COM class or create a C++/Clr project. C++/CLR can call native C++ code/classes and expose .NET types. – shf301 May 10 '12 at 17:32
  • @shf301-- can you please provide me a sample code how to do that? – krishna555 May 10 '12 at 17:34

2 Answers2

1

I don't see where you export the C++ function??? You define the t72... func as "static" ??? You want it to only be visible in the .cpp file it is defined in???

I suggest defining your C++ func as:

extern "C" bool WINAPI t72CalculateRMDMethodResult( const double     AccountBalanceAtSetup,
                                     const long       ClientCurrentAge,
                                     const char       Frequency,
                                     double *         pRMDMethodResult,
                                     IRSLookupTable & LookupTable)

Edit your .def file and add an export entry for t72CalculateRMDMethodResult.

You can use "dumpbin /exports mydll.dll" to determine if the function was exported properly. (obviously substitute your dll for mydll.dll)

Joseph Willcoxson
  • 5,853
  • 1
  • 15
  • 29
  • i don't have right to change the c++ code that is why i am trying to figure out any other ways available. As i must have to use those parts of the c++ code and do testing using c# but not supposed to changed the c++ code so is there any other way to do this with out touching c++ code. Please provide some sample code.. – krishna555 May 10 '12 at 17:54
  • You need to call "dumpbin /exports yourdll.dll" (substitute your dll) to see if the function is exported. If it is not, then you are stuck. – Joseph Willcoxson May 10 '12 at 19:08
  • yes i tried it and it didn't get exported as it has a class pointer as an argument to the function and i am unable to match both the pointers in c++ function and the c# function i am stuck there, of course that is the problem that i am having from the beginning. Please let me know if any thing comes up in your mind regarding this. Thank you very much for your help... – krishna555 May 10 '12 at 19:13
  • If it's not exported, there is nothing you can do. It takes rebuilding the DLL and exporting the function. – Joseph Willcoxson May 10 '12 at 19:17
0

If you can't change the C++ code, then you may be able to write a C++/CLI layer that will expose it to the C# code. This way you can avoid any ugly DLL imports and exports (I never learned how to do that).m With this technique you can leave your C++ code completely untouched.

I'm assuming you're using at least VS2005 since you mentioned C#.

Check out this post C++/CLI Mixed Mode DLL Creation

Community
  • 1
  • 1
Ian
  • 4,169
  • 3
  • 37
  • 62