2012-01-19 42 views
8

Khác với tăng (Bind & Chức năng), làm cách nào để tự động gọi hàm trong C++?cách tự động gọi hàm bằng C++

PHP có:

$obj = new MyObject(); 
$function = 'doSomething'; 
$obj->$function(); 

Objective-C có:

MyObject *obj = [[MyObject alloc] init]; 
SEL function = NSSelectorFromString(@"doSomething"); 
[obj performSelector: function]; 
+0

http://stackoverflow.com/questions/11016078/is-it-possible -to-create-a-function-động-trong-thời gian chạy-in-c – dtech

+0

Từ khóa tìm kiếm liên quan: Trong C++ tìm kiếm "chức năng ảo" và "ràng buộc muộn hoặc liên kết động". Trong C "con trỏ đến hàm". – lepe

Trả lời

2

Nếu những chức năng bạn đang quan tâm là của cùng một loại, bạn có thể tạo bản đồ của chuỗi và con trỏ hàm.

+0

Điều đó có nghĩa là tôi cần giữ danh sách cập nhật. Tôi đang tìm kiếm tự động hơn. – joels

+0

Bạn có thể sử dụng một số chương trình để tạo ra nó (thậm chí có thể ctags với một chút sed ở cuối) – stralep

+0

@joels - tạo mã dễ dàng. – dtech

2

Câu trả lời đơn giản là bạn không thể. C++ không làm phương thức tra cứu theo tên.

+1

Sai, bạn có thể tra cứu hàm DLL theo tên. – dtech

+2

@ddriver DLL không phải là một phần của C++ và các hàm DLL không phải là các phương thức C++. – Roddy

+0

@Roddy - bạn có thể biên dịch C++ thành DLL và lấy con trỏ đến hàm bằng tra cứu tên. DLL trên cửa sổ, vì vậy trên Linux, bất cứ điều gì, bạn có thể tra cứu chức năng trong thư viện động theo tên, đó là một thực tế. – dtech

8

Bạn có thể xuất các chức năng cần thiết (ví dụ như bằng cách đánh dấu chúng với __dllexport) và sử dụng GetProcAddress hoặc dlsym (tùy thuộc vào nền tảng của bạn) để nhận địa chỉ của họ:

 

void *handle = dlsym(0, RTLD_LOCAL | RTLD_LAZY); 
FunctionType *fptr = (FunctionType *)dlsym(handle, "doSomething"); 
fptr(); 
 
 

HANDLE handle = GetCurrentProcess(); 
FunctionType *fptr = (FunctionType *)GetProcAddress(handle, "doSomething"); 
fptr(); 
 

Tất cả điều này là nền tảng cụ thể mặc dù và không có cách nào tiêu chuẩn trong C++ để làm điều này.

+3

Không thể phàn nàn, đó là câu trả lời hay.Tuy nhiên tôi sẽ chỉ ra rằng nó là tuyệt vời cho các cuộc gọi năng động đến các chức năng C, và sẽ không làm việc cho các cuộc gọi phương thức C++ đa hình. –

+0

@GrahamPerks: vâng, nó sẽ chỉ có nền tảng cụ thể hơn với những thứ như xoài, điều chỉnh đối tượng con trỏ và thích, nhưng không hoàn toàn không thể. Mặc dù, tôi nghi ngờ tôi sẽ bao giờ làm điều đó trong môi trường sản xuất. –

+1

Bạn cũng có thể đánh dấu các hàm bạn muốn tham chiếu với "C" bên ngoài trong phần khai báo để ngăn không cho tên bị xé trong quá trình biên dịch. extern "C" void hello() { std :: cout << "Xin chào \ n"; } Điều này sẽ cho phép bạn gọi hàm theo tên. void * handle = dlsym (0, RTLD_LOCAL | RTLD_LAZY); FunctionType * fptr = (FunctionType *) dlsym (xử lý, "hello"); fptr(); Đây là những gì bên ngoài "C" làm theo mui xe: http://stackoverflow.com/questions/1041866/in-c-source-what-is-the-effect-of-extern-c – deadbabykitten

2

Nếu tôi hiểu câu hỏi của bạn đúng cách, bạn có thể sử dụng con trỏ hàm (hoặc con trỏ tới thành viên) trong C++. Bạn có thể tự động quyết định cuộc gọi hàm nào (bạn có thể cần một nguyên mẫu giống nhau) và gọi nó là động. Xem liên kết này

https://isocpp.org/wiki/faq/pointers-to-members

2

Mở rộng về câu trả lời Konstantin Oznobihin để các câu hỏi, bạn có thể đánh dấu các C++ chức năng bạn đang tham khảo với extern "C" trong việc kê khai để ngăn chặn các trình biên dịch từ mangling tên trong biên dịch.

extern "C" void hello() { 
    std::cout << "Hello\n"; 
} 

Điều này sẽ cho phép bạn gọi đối tượng/chức năng của mình theo tên ban đầu bạn đã đặt. Trong trường hợp này, nó là 'hello'.

void *handle = dlsym(0, RTLD_LOCAL | RTLD_LAZY); 
FunctionType *fptr = (FunctionType *)dlsym(handle, "hello"); 
fptr(); 

Có một loạt các điều extern "C" không dưới mui xe, vì vậy đây là một danh sách ngắn: In C++ source, what is the effect of extern "C"?

+0

Vui lòng chỉnh sửa và thêm câu trả lời này vào câu trả lời của @KonstantinOznobihin. Dù sao, cảm ơn cho tip tốt. – Jet

Các vấn đề liên quan