The get_post_permalink() funciton fetches the link to a post depending on its “permanent” link plus your custom rewrite rules that changes ?p=123 into for e.g. my-beautiful-sunday-diary. The get_permalink() function is more “basic” but as well more versatile in what it does: For a post_type of
page, it usesget_page_link()attachment, it usesget_attachment_link()post, it usesget_post_link()
It also handles the display of terms like category and date permalinks. At the end, it either replaces the “pretty” link in your home_url() or just returns the raw link if no custom rewrite rules were assigned. Finally it attaches a generic filter:
/**
* Filters the permalink for a post.
*
* Only applies to posts with post_type of 'post'.
*
* @since 1.5.0
*
* @param string $permalink The post's permalink.
* @param WP_Post $post The post in question.
* @param bool $leavename Whether to keep the post name.
*/
return apply_filters( 'post_link', $permalink, $post, $leavename );
Hope that clarifies the topic.
ProTip: If you need to change peramlinks in a plugin, go with the specific filters inside get_attachment_link(), get_post_link(), etc. Only if you are either working on a single site and are not planning to distribute your code or if you are writing a plugin targetting only rewrite stuff, then go with the generic filter above. Else you will nuke every theme authors efforts and start a callback priority race.