Q&A

  • C++소스를 델파이로 옮기려고 하는데. 도움좀 주세요.
IMSL이라는 통계모듈을 델파이에서 쓰려고 하는데요.
자주 접하는것이 아니라서.. 참 어렵습니다.
아래 예제를 그대로 옮기는것도 힘들어서 여기 질문을 합니다.


메뉴얼에 있는 C++예제입니다.
main()
{
void fcn(int, float *, float *);
int neq = 2;
int ncon = 2;
int nvar = 5;
float a[] = {1.0, 1.0, 1.0, 1.0, 1.0,
              0.0, 0.0, 1.0, -2.0, -2.0};
float b[] = {5.0, -3.0};
float xlb[] = {0.0, 0.0, 0.0, 0.0, 0.0};
float xub[] = {10.0, 10.0, 10.0, 10.0, 10.0};
float *x;
x = imsl_f_min_con_gen_lin(fcn, nvar, ncon, neq, a, b, xlb, xub, 0);
//imsl_f_write_matrix("Solution", 1, nvar, x, 0);
}

void fcn(int n, float *x, float *f)
{
*f = x[0]*x[0] + x[1]*x[1] + x[2]*x[2] + x[3]*x[3] + x[4]*x[4]
- 2.0*x[1]*x[2] - 2.0*x[3] * x[4] - 2.0*x[0];
}

imsl_f_min_con_gen_lin 이 함수를 테워서 값을 얻는것이 목적이구요..
인자로 처음에 함수가 들어갑니다.
(이것이 되나요? 함수를 데이터 타입처럼 하려고 하는데.. 쉽지가 않습니다.)


imsl_f_min_con_gen_lin의 함수 원형은 아래와 같습니다.
float *imsl_f_min_con_gen_lin (void fcn(), int nvar, int ncon, int a,
  float b, float xlb[], float xub[],
  IMSL_XGUESS, float xguess[],
  IMSL_GRADIENT, void gradient(),
  IMSL_MAX_FCN, int max_fcn,
  IMSL_NUMBER_ACTIVE_CONSTRAINTS, int *nact,
  IMSL_ACTIVE_CONSTRAINT, int **iact,
  IMSL_ACTIVE_CONSTRAINT_USER, int *iact_user,
  IMSL_LAGRANGE_MULTIPLIERS, float **lagrange,
  IMSL_LAGRANGE_MULTIPLIERS_USER, float *lagrange_user,
  IMSL_TOLERANCE, float tolerance,
  IMSL_OBJ, float *obj,
  IMSL_RETURN_USER, float x[], 0)

위와 같이 많은 인수들이 있고, 예제는 인수를 전부 사용하지 않습니다.

또 한가지 질문은..
DLL에 선언이 된 위와같은 함수를 델파이로 옮겨 오려면..
함수 원형을 그대로 옮겨야 하나요? 아니면, 제가 필요한 부분만 옮겨도 되나요.
예를들어 예제처럼 델파이로 옮긴다면.
function imsl_f_min_con_gen_lin(var fcn; nvar, ncon, neq: Integer;
                         a: array of Double; b: array of double;
                         xlb: array of double; xub: array of double;
                         aa: integer ):single; stdcall; external 'cmath.dll';
이렇게 옮겨도 되는건가요?



델파이도 잘 모르는데.. C++까지 하려니 너무 어렵습니다.
많은 도움 바랍니다..



첨부파일은 지금껏 제가 옮기다가 실패한 소스 입니다.
Del6 이구요. 현재 컴파일이 안됩니다..
3  COMMENTS
  • Profile
    최용일 2005.03.21 22:58
    안녕하세요. 최용일입니다.

    함수 원형은 그대로 유지를 하셔야 합니다. DLL도 일종의 규약이니까요...

    array of 는 델파이만의 고유한것입니다.

    xlb = array[0..0] of Float; 나 포인터를 쓰시는게....

    IMSL_로 시작되는것은 뭔지......... 데이터 형도 없구... 난해하네요....

    별도움이 못되는거 같군요.... ㅠㅠ

    ^^ 항상 즐코하세요...

  • Profile
    아마존 2005.03.21 23:09
    네.. 답변 감사합니다.

    array of를 쓰면 안되는 것이군요..

    제가 array of를 쓴 이유는 배열 변수들이 유동적입니다.
    위에서 선언된 neq, ncon, nvar에 따라서 배열의 갯수가 결정이 됩니다.
    이 말을 미리 적지 않아 죄송합니다.
    그러면.. 배열 변수들은 전부 포인트 형이 되어야 되네요(휴..)
    그리고, 함수의 원형에 델파이에서도 그 원형대로 변환을 하면 되는거군요..
    예제에 그 원형에 따라서 쓰지 않길래 잘 몰랐었습니다.


    IMSL_ 로 시작하는것들은 상수입니다.
    헤더 파일에 보니 상수값을 취하고 있길래,
    제가 첨부한 예제에서는 .h파일을 보고 const값을 적어 놓았습니다..


    하나 더 질문을 해도 될까요?
    변환 도중 제일 모르겠는것이 함수형태의 자료형입니다.

    x = imsl_f_min_con_gen_lin(fcn, nvar, ncon, neq, a, b, xlb, xub, 0);
    이라고 되어 있는 부분에서 fcn은 함수이고, 결과값은 인수로 받은 포인터 형에 넣습니다.

    이 부분이 정말 안되어서요..
    노력은 계속하고 있지만, 아직도 컴파일이 안됩니당 ..


    빠른답변 감사드립니다..


  • Profile
    최용일 2005.03.22 00:12
    안녕하세요. 최용일입니다.

    상수일지라도 데이터형이 있을테니까 그 형에 따라서 헤더를 적어주시면 될테구요...

    함수포인터는 아래와 같은식으로 해보세요...

    밑에 fcn은 계산하기 편하게 하나는 포인터, 하나는 var로 했는데... 맞을려나 모르겠네요....

    C의 콜백함수라면... 호출규약을 확인하세요... stdcall인지 cdecl인지...

    <!--CodeS-->

    type
        PDoubleArray = ^TDoubleArray;
        TDoubleArray = array[0..(MaxInt div 8)-1] of Double;
    type
        TfcnProc = procedure (n: Integer; X: PDoubleArray; var F: Double); stdcall;

    procedure fcn(n: Integer; X: PDoubleArray; var F: Double); stdcall;
    begin
        F := x[0]*x[0] + x[1]*x[1] + x[2]*x[2] + x[3]*x[3] + x[4]*x[4]
            - 2.0*x[1]*x[2] - 2.0*x[3] * x[4] - 2.0*x[0];
    end;

    procedure Callfcn(fcnProc: TfcnProc);
    begin
      ......
    end;

    // Call Sample
    begin
        Callfcn(fcn);
    end;

    <!--CodeE-->

    ^^ 항상 즐코하세요...