2010-05-19 2 views
3

Autant que je sache - Les sous-programmes sont en mode d'accès privé à leur onction/procédure parentale, n'est-ce pas?Accès aux sous-fonctions/procédures à partir de DPR ou d'une autre fonction/procédure dans Delphi

Y a-t-il un moyen d'y accéder à partir de "monde extérieur" - dpr ou autre fonction/procédure dans l'unité?

Aussi - quel chemin prend plus de calcualtion et d'espace pour le fichier compilé?

par exemple:

function blablabla(parameter : tparameter) : abcde; 
procedure xyz(par_ : tpar_); 
begin 
    // ... 
end; 
begin 
// ... 
end; 

procedure albalbalb(param : tparam) : www; 
begin 
xyz(par_ : tpar_); // is there any way to make this function public/published to access it therefore enabling to call it this way? 
end; 

// all text is random. 

// also, is there way to call it from DPR in this manner? 

// in C++ this can be done by specifing access mode and/or using "Friend" class .. but in DELPHI? 
+0

Privé est privé :) Êtes-vous à la recherche d'un moyen de le rendre public sans changer le code? – mjn

+0

Ce n'est même pas privé, c'est interne. Il n'existe pas en dehors de la routine "parent" où il est intégré. –

Répondre

5

Remarque: Routines incorporées > Méthodes privées/protégées.

Les routines intégrées, c'est-à-dire les routines internes aux routines, ne sont pas accessibles par des routines externes. Vous avez posté un exemple de routine Embedded, je les ai également entendu appeler Internal Routines.

Voici un autre exemple:

procedure DoThis; 

function DoThat : Boolean; 
begin 
    // This Routine is embedded or internal routine. 
end; 
begin 

// DoThat() can only be accessed from here no other place. 

end; 

Quelle que soit la visibilité, les méthodes sur les classes, peuvent être appelées à l'aide Delphi 2010 via RTTI. J'ai détaillé comment faire cela dans this article.

Si vous êtes dans la même unité Les méthodes sur une classe peuvent être accédées par n'importe quel autre code indépendamment de la visibilité, sauf si elles sont marquées avec Strict Private. This Question a plus de détails et un bon exemple de code dans le accepted answer.

Si vous appartenez à deux unités différentes, vous pouvez utiliser la méthode protégée Hack pour accéder aux méthodes protégées. Ce qui est détaillé en détail dans this article.

2

Non, il n'y a pas moyen de faire ce que vous demandez. La fonction xyz est appelable seulement par la fonction blablabla englobante. En dehors de cette fonction, xyz n'est pas dans la portée et il n'y a aucun moyen de le nommer. Si C++ permettait une fonction imbriquée, il n'y aurait pas non plus de moyen de s'y référer, tout comme il n'y a aucun moyen de faire référence à des fonctions avec une liaison statique provenant de l'extérieur de l'unité de traduction en cours.

Si vous devez appeler xyz à l'extérieur de la fonction blablabla, déplacez xyz à l'extérieur. Si vous devez l'appeler depuis l'extérieur de l'unité actuelle, vous devez déclarer cette fonction dans la section d'interface de l'unité. Ensuite, ajoutez cette unité à la clause uses du code externe et vous pouvez appeler le xyz d'où vous voulez, même le fichier DPR. Si xyz fait référence à des variables ou à des paramètres de la fonction blablabla, vous devrez les transmettre en tant que paramètres puisque xyz n'y aura plus accès autrement.

Le concept des spécificateurs d'accès n'est pas vraiment pertinent ici car il ne s'agit pas de classes. Les unités ont l'interface et sections mise en œuvre, qui ne sont pas vraiment les mêmes que publique et privés sections d'une classe.

7

Les procédures/fonctions imbriquées - celles déclarées dans une autre procédure ou fonction, sont un type spécial, car elles peuvent accéder à la pile (et donc aux paramètres/variables locales) de la procédure dans laquelle elles sont imbriquées. règles de portée, il n'y a aucun moyen d'y accéder en dehors de la procédure "parent". Vous les utilisez uniquement si vous avez besoin de profiter de leurs fonctionnalités spéciales. AFAIK Delphi/Pascal est l'une des rares langues à avoir cette fonctionnalité. Du point de vue du compilateur, l'appel a du code supplémentaire pour permettre l'accès au cadre de la pile parent, IIRC. AFAIK les classes/amis "friend" en C++ sont différentes - ce sont des méthodes d'accès à la classe, alors que dans votre exemple vous utilisez des procédures/fonctions simples. En Delphi, toutes les procédures/classes déclarées dans la même unité sont automatiquement "friend", à moins que les déclarations privées strictes ne soient utilisées dans les dernières versions de Delphi. Par exemple des extraits de ce code fonctionne, tant tout est dans la même unité:

type 
    TExample = class 
    private 
     procedure HelloWorld; 
    public 
    ... 
    end; 

    implementation 

    function DoSomething(AExample: TExample); 
    begin 
     // Calling a private method here works 
     AExample.HelloWordl; 
    end; 
3

Oui, vous pouvez accéder à un sous-programme, qui est imbriqué dans un autre sous-programme (parent), du monde extérieur. Bien que ce soit un peu difficile. J'ai trouvé ce howto sur le web.

Comment passer de routine imbriquée comme paramètre de procédure (32 bits)

Delphi ne normalement supporte pas le passage des routines imbriquées comme paramètres de procédure:

// This code does not compile: 
procedure testpass(p: tprocedure); 
begin 
    p; 
end; 
procedure calltestpass; 
procedure inner; 
begin 
    showmessage('hello'); 
end; 
begin 
    testpass(inner); 
end; 

La solution évidente consiste à passer l'adresse de procédure et cataloguée dans un délai testpass:

// This code compiles and runs OK 
procedure testpass(p: pointer); 
begin 
    tProcedure(p); 
end; 
procedure calltestpass; 
procedure inner; 
begin 
    showmessage('hello'); 
end; 
begin 
    testpass(@inner); 
end; 

il y a, cependant, un piège dans e e exemple ci-dessus - si la routine "inner" référence une variable qui a été poussée sur la pile avant que la procédure "inner" soit appelée depuis testpass (paramètres calltestpass - s'il y en avait, ou variables locales dans calltestpass - s'il y en avait), votre système le plus probablement tombe en panne:

// This code compiles OK but generates runtime exception (could even be 
// EMachineHangs :-)) 
procedure testpass(p: pointer); 
begin 
    tProcedure(p); 
end; 
procedure calltestpass; 
var msg: string; 
procedure inner; 
begin 
    msg := 'hello'; 
    showmessage(msg); 
end; 
begin 
    testpass(@inner); 
end; 

la raison en est, en termes simples, que l'agencement de cadre de pile était « cassée » par l'appel à testpass de routine et de la procédure « intérieure » calcule correctement l'emplacement des paramètres et des variables locales (ne blâmez pas Delphi, s'il vous plaît). La solution de contournement consiste à définir le contexte de pile correct avant d'appeler "inner" depuis "testpass". Veuillez noter que l'optimisation est désactivée pour la routine de test - l'optimisation ne gère généralement pas très bien le code OP/assembleur mixte.

Questions connexes