banner

[Rule] Rules  [Home] Main Forum  [Portal] Portal  
[Members] Member Listing  [Statistics] Statistics  [Search] Search  [Reading Room] Reading Room 
[Register] Register  
[Login] Loginhttp  | https  ]
 
Forum Index Thảo luận hệ điều hành Windows Function Pointer trong C++  XML
  [Programming]   Function Pointer trong C++ 02/12/2007 13:53:41 (+0700) | #1 | 101525
[Avatar]
havythoai
HVA Friend

Joined: 05/04/2004 22:59:39
Messages: 562
Offline
[Profile] [PM] [WWW]
Hi các bạn !

Có 1 vấn đề tớ thắc mắc, mà chưa giải quyết được, mặc dù đã google lỗi này, và làm theo nhưng ko thành công

Tớ có 1 file viết bằng C (constructive.c) với nội dung như sau:

/*constructive.c Constructive Solid Geometry*/

#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>

void firstInsideSecond(void (*a) (void), void (*b) (void), GLenum face, GLenum test)
{
glEnable(GL_DEPTH_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glCullFace(face); /* controls which face of a to use */
a(); /* draw a face of a into depth buffer */

/* use stencil plane to find parts of a in b */
glDepthMask(GL_FALSE);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 0, 0);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glCullFace(GL_BACK);
b(); /* increment the stencil where the front face of b is drawn */

glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
glCullFace(GL_FRONT);
b(); /* decrement the stencil buffer where the back face
of b is drawn */
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

glStencilFunc(test, 0, 1);
glDisable(GL_DEPTH_TEST);

glCullFace(face);
a(); /* draw the part of a that's in b */
}


void fixDepth(void (*a) (void))
{
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glDepthFunc(GL_ALWAYS);
a(); /* draw the front face of a, fixing the depth buffer */
glDepthFunc(GL_LESS);
}

/* "and" two objects together */
void and(void (*a) (void), void (*b) (void))
{
firstInsideSecond(a, b, GL_BACK, GL_NOTEQUAL);
fixDepth(b);
firstInsideSecond(b, a, GL_BACK, GL_NOTEQUAL);
glDisable(GL_STENCIL_TEST); /* reset things */
}

/* subtract b from a */
void sub(void (*a) (void), void (*b) (void))
{
firstInsideSecond(a, b, GL_FRONT, GL_NOTEQUAL);
fixDepth(b);
firstInsideSecond(b, a, GL_BACK, GL_EQUAL);
glDisable(GL_STENCIL_TEST); /* reset things */
}
 


Sau đó tớ include file này vào trong file main.cpp để sử dụng các hàm trong file đó. Nội dụng trong file main.cpp như sau:


#include "constructive.c"

class CMaSim
{
public:
...
void Subtract();
void RenderCutter();
void RenderObject();
...
}

void CMaSim::Subtract()
{
sub( RenderCutter, RenderObject); // <----- bi ba'o loi


Sau khi chạy thì bị báo lỗi ở dòng màu vàng trên với nội dung lỗi là

error C2664: 'sub' : cannot convert parameter 1 from 'void (void)' to 'void (__cdecl *)(void) 


Giờ ko biết sửa thế nào đây, mong các bạn đưa ra giải pháp giúp đỡ
[Up] [Print Copy]
  [Question]   Function Pointer trong C++ 02/12/2007 14:00:47 (+0700) | #2 | 101527
[Avatar]
havythoai
HVA Friend

Joined: 05/04/2004 22:59:39
Messages: 562
Offline
[Profile] [PM] [WWW]
Double posts, Mod nào xóa hộ tớ post này nhé
[Up] [Print Copy]
  [Question]   Re: Function Pointer trong C++ 02/12/2007 15:02:11 (+0700) | #3 | 101537
[Avatar]
Thomas_Black
Member

[Minus]    0    [Plus]
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
[Profile] [PM]
Thực ra bạn đã nhầm lẫn giữa pointer-to-member-functionpointer-to-function. Pointer-to-member-function có dạng (lấy ví dụ của bạn nhé):
Code:
void RenderCutter(CMaSim::*)(void)

là một thành phần non-static của class CMaSim. Trong khi đó, nếu RenderCutter là một function đơn lẻ, nó sẽ có dạng:
Code:
void RenderCutter(*)(void)

Với đoạn code trên mình có 2 cách sửa:
  • [*](Thông dụng) Thêm một member static, giả sử:
  • Code:
  • class CMaSim
    {
        public:
        void Subtract();
    	void RenderCutter();
        static void staticRenderCutter() {
        }
    	void RenderObject();
        static void staticRenderObject() {
        }
    };
  • Lúc đó bạn gọi
  • Code:
  • sub(staticRenderCutter, staticRenderObject);
  • như bình thường
  • [*](Dễ dùng hơn) Dùng wrapper function, như thế này chẳng hạn
  • Code:
  • CMaSim *wrapperObj;
    
    void wrapperRenderCutter() {
    	return wrapperObj->RenderObject();
    }
    
    void wrapperRenderObject() {
    	return wrapperObj->RenderObject();
    }
  • Lúc đó, bạn gọi:
  • Code:
  • sub( wrapperRenderCutter, wrapperRenderObject );
  • là ổn

Chúc bạn thành công.
P.S: Mod sửa lại thẻ list giùm mình với smilie, sao BBCode nó không lên nhỉ
[Up] [Print Copy]
  [Question]   Re: Function Pointer trong C++ 04/12/2007 13:54:26 (+0700) | #4 | 101842
[Avatar]
havythoai
HVA Friend

Joined: 05/04/2004 22:59:39
Messages: 562
Offline
[Profile] [PM] [WWW]
Cám ơn bạn.

Tớ đã thử trường hợp dùng static nhưng chương trình của tớ khá đồ sộ. Vì bên trong hàm RenderCutter() còn có đủ thứ hàm khác như RenderCylinder() chẳng hạn, nếu ta cho RenderCutter() là static, thì trình duyệt báo lỗi là hàm RenderCylinder() cũng phải để static... dẫn đến 1 dãy các hàm static, và chương trình của tớ làm viec ko đúng.

Nếu dùng cách thứ 2 thì hàm wrapperRenderCutter() , và wrapperRenderObject() tớ chả biết khai báo trong Class nào smilie. nếu để trống trơn như thế thì bị báo lỗi. Nếu khai báo trong 1 class nào đó thì sẽ quay trở lại lỗi ban đầu. Hiện tại tớ dùng complier Visual C++ 6.0, lập trình trên MFC, dùng giao diện SDI.

Tớ đã nghĩ ra cách giải quyết, ko pro, nghĩa là gom tất cả những gì của các hàm trong file constructive.c vào 1 hàm member của Class MaSim, và đã chạy được, chỉ bị lỗi hiển thị phần đồ hoạ OpenGL (đang tìm cách khắc phục)

Code:
void CMaSimView:Subtract()
{
  glEnable(GL_DEPTH_TEST);
  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  glCullFace(GL_FRONT);     /* controls which face of a to use */
  RenderCutter();                  /* draw a face of a into depth buffer */

  /* use stencil plane to find parts of a in b */
  glDepthMask(GL_FALSE);
  glEnable(GL_STENCIL_TEST);
  glStencilFunc(GL_ALWAYS, 0, 0);
  glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
  glCullFace(GL_BACK);
  RenderObject();             /* increment the stencil where the front face of b is 
                           drawn */
  glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
  glCullFace(GL_FRONT);
  RenderObject();             /* decrement the stencil buffer where the back face of b is drawn */

  glDepthMask(GL_TRUE);
  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

  glStencilFunc(GL_NOTEQUAL, 0, 1);
  glDisable(GL_DEPTH_TEST);

  glCullFace(GL_FRONT);
 RenderCutter();

  ////////////////////
  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_STENCIL_TEST);
  glDepthFunc(GL_ALWAYS);
  RenderObject();                  /* draw the front face of a, fixing the depth buffer */
  glDepthFunc(GL_LESS);
  /////////////////

  glEnable(GL_DEPTH_TEST);
  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  glCullFace(GL_BACK);     /* controls which face of a to use */
  RenderObject();                  /* draw a face of a into depth buffer */

  /* use stencil plane to find parts of a in b */
  glDepthMask(GL_FALSE);
  glEnable(GL_STENCIL_TEST);
  glStencilFunc(GL_ALWAYS, 0, 0);
  glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
  glCullFace(GL_BACK);
  RenderCutter();                  /* increment the stencil where the front face of b is 
                           drawn */
  glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
  glCullFace(GL_FRONT);
  RenderCutter();                  /* decrement the stencil buffer where the back face
                           of b is drawn */
  glDepthMask(GL_TRUE);
  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

  glStencilFunc(GL_EQUAL, 0, 1);
  glDisable(GL_DEPTH_TEST);

  glCullFace(GL_BACK);
 RenderObject();

  glDisable(GL_STENCIL_TEST);
}

[Up] [Print Copy]
[digg] [delicious] [google] [yahoo] [technorati] [reddit] [stumbleupon]
Go to: 
 Users currently in here 
1 Anonymous

Powered by JForum - Extended by HVAOnline
 hvaonline.net  |  hvaforum.net  |  hvazone.net  |  hvanews.net  |  vnhacker.org
1999 - 2013 © v2012|0504|218|