http://msdn.microsoft.com/

http://www.ddj.com/cpp/184

Solved

Posted on 2009-04-27

I am missing something simple here. I have created a roots routine from the Numerical Recipes book in a c++ class and saved it as a .dll . That builds and I think is good. What I am am failing to figure out is how to call it in my C# application. It appears as though the methods in C++ are set to private but they are most definitely set to public. I have referenced the dll file in my C# project and have used an including statement at the top and can see the namespace and the class but not the method. The details of the C++ code have been left out for copyright /respect reasons and I don't think they are the cause of the problem here.

```
C++ code:
#include "nr3.h"
using namespace System;
namespace Numerical_Methods
{
public ref class Roots
{
public:
static void laguer(VecComplex_I &a, Complex &x, Int &its)
{
laguer code.
}
static void zroots(VecComplex_I &a, VecComplex_O &roots, const Bool &polish)
{
polish code for laguere.
}
};
}
```

11 Comments

http://msdn.microsoft.com/

http://www.ddj.com/cpp/184

Can you try to add a method that has all the paremeters of .NET types?

How VecComplex_I, VecComplex_O and Complex are defined?

static void laguer(VecComplex_I^ a, Complex^ x, Int its) gave all sorts of errors. Like

Error 1 error C3699: '^' : cannot use this indirection on type 'VecComplex_I'

Error 2 error C3699: '^' : cannot use this indirection on type 'Complex'

Error 3 error C2228: left of '.size' must have class/struct/union

Error 4 error C2679: binary '=' : no operator found which takes a right-hand operand of type 'VecComplex_I' (or there is no acceptable conversion)

Error 5 error C2665: 'std::abs' : none of the 6 overloads could convert all the argument types

Error 6 error C2678: binary '*' : no operator found which takes a left-hand operand of type 'Complex *' (or there is no acceptable conversion)

Error 7 error C2678: binary '*' : no operator found which takes a left-hand operand of type 'Complex *' (or there is no acceptable conversion)

Error 8 error C2678: binary '*' : no operator found which takes a left-hand operand of type 'Complex *' (or there is no acceptable conversion)

Error 9 error C2679: binary '-' : no operator found which takes a right-hand operand of type 'Complex' (or there is no acceptable conversion)

Error 10 error C2679: binary '==' : no operator found which takes a right-hand operand of type 'Complex' (or there is no acceptable conversion)

Error 11 error C2440: '=' : cannot convert from 'Complex' to 'Complex *'

Error 12 error C2677: binary '-=' : no global operator found which takes type 'std::complex<double>' (or there is no acceptable conversion)

Error 13 error C2664: 'Numerical_Methods::Roots:

Error 14 error C2664: 'Numerical_Methods::Roots:

```
// Numerical_Methods.h
#pragma once
#include "nr3.h"
using namespace System;
namespace Numerical_Methods
{
public ref class Roots
{
public:
static void laguer(VecComplex_I^ a, Complex^ x, Int &its)
{
const Int MR=8, MT=10, MAXIT =MT*MR;
const Doub EPS=numeric_limits<Doub>::epsilon();
static const Doub frac[MR+1]=
{0.0,0.5,0.25,0.75,0.13,0.38,0.62,0.88,1.0};
Complex dx,x1,b,d,f,g,h,sq,gp,gm,g2;
Int m=a.size()-1;
for (Int iter = 1; iter<=MAXIT; iter++)
{
its = iter;
b=a[m];
Doub err=abs(b);
d=f=0.0;
Doub abx =abs(x);
for (Int j=m-1;j>=0;j--)
{
f=x*f*d;
d=x*d+b;
b=x*b+a[j];
err=abs(b)+abx*err;
}
err *=EPS;
if(abs(b)<=err) return;
g=d/b;
g2=g*g;
h=g2-2.0*f/b;
sq = sqrt(Doub(m-1)*(Doub(m)*h-g2));
gp=g+sq;
gm=g-sq;
Doub abp =abs(gp);
Doub abm = abs(gm);
if(abp<abm) gp=gm;
dx=MAX(abp,abm)>0 ? Doub(m)/gp : polar(1+abx,Doub(iter));
x1=x-dx;
if(x==x1) return;
if (iter % MT != 0) x=x1;
else x -= frac[iter/MT]*dx;
}
throw("too many iterations in laguer");
}
static void zroots(VecComplex_I a, VecComplex_O roots, const Bool polish)
{
const Doub EPS=1.0e14;
Int i, its;
Complex x,b,c;
Int m=a.size()-1;
VecComplex ad(m+1);
for (Int j=0;j<=m; j++) ad[j]=a[j];
for (Int j=m-1;j>=0;j--)
{
x=0.0;
VecComplex ad_v(j+2);
for(Int jj=0;jj<j+2;jj++) ad_v[jj]=ad[jj];
laguer(ad_v,x,its);
if(abs(imag(x)) <= 2.0*EPS*abs(real(x)))
x=Complex(real(x),0.0);
roots[j]=x;
b=ad[j+1];
for (Int jj=j;jj>=0;jj--)
{
c=ad[jj];
ad[jj]=b;
b=x*b+c;
}
}
if(polish)
for (Int j=0;j<m;j++)
laguer(a,roots[j],its);
for(Int j=1;j<m;j++)
{
x=roots[j];
for (i=j-1; i>=0;i--)
{
if (real(roots[i])<=real(x)) break;
roots[i+1]=roots[i];
}
roots[i+1]=x;
}
}
};
}
```

static void test(double in)

{

double tets = in;

}

What could it be about the header file/ custom variables that it doesn't like?

"Writing Managed Wrappers with Managed C++" at

http://www.ondotnet.com/pu

I can't explain every little thing that may be going wrong here, but on top of the name-mangling, your probably may lie in the CLS (Common Language Specification), and whether or not these objects you're handling in C++ are CLS-Compliant. The reason these objects must be "compliant" is because every native C++ type you use in C# must be "mapped out" to a corresponding type in C# (for example, Native C++'s "char" primitive type maps out the a "System.SByte" in VC#).

A third problem may arise from VC# being so strict about having some sort of a passion for hating pointers. Any code block that utilizes pointers in VC# MUST appear within an "unsafe" block, as well as the entire assembly be compiled with the /unsafe switch. This essentially overrides some of the .NET Framework's type-safety checking, allowing for pointers, the useage of the stackalloc keyword, among other things.

By clicking you are agreeing to Experts Exchange's Terms of Use.

Title | # Comments | Views | Activity |
---|---|---|---|

Unresolved External Symbols | 3 | 30 | |

add array of labels to a panel in C# winforms | 3 | 26 | |

Gridview redisplays hidden columns afer postback | 2 | 23 | |

How to convert MFC::CString to UTF8 wchar_t* | 10 | 34 |

Join the community of 500,000 technology professionals and ask your questions.

Connect with top rated Experts

**10** Experts available now in Live!